diff --git a/HsDirectoryConfig.h.in b/HsDirectoryConfig.h.in
--- a/HsDirectoryConfig.h.in
+++ b/HsDirectoryConfig.h.in
@@ -3,6 +3,9 @@
 /* Filename extension of executable files */
 #undef EXE_EXTENSION
 
+/* Define to 1 if you have the `CreateSymbolicLinkW' function. */
+#undef HAVE_CREATESYMBOLICLINKW
+
 /* Define to 1 if you have the <fcntl.h> header file. */
 #undef HAVE_FCNTL_H
 
@@ -15,12 +18,15 @@
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
 
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
@@ -63,5 +69,7 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,9 +3,10 @@
 
 [![Hackage][hi]][hl]
 [![Build status][bi]][bl]
-[![Windows build status][wi]][wl]
+[![Dependencies status][di]][dl]
 
 Documentation can be found on [Hackage][hl].
+Changes between versions are recorded in the [change log](changelog.md).
 
 Building from Git repository
 ----------------------------
@@ -22,8 +23,8 @@
 
 [hi]: https://img.shields.io/hackage/v/directory.svg
 [hl]: https://hackage.haskell.org/package/directory
-[bi]: https://travis-ci.org/haskell/directory.svg?branch=master
-[bl]: https://travis-ci.org/haskell/directory
-[wi]: https://ci.appveyor.com/api/projects/status/github/haskell/directory?branch=master&svg=true
-[wl]: https://ci.appveyor.com/project/hvr/directory
+[bi]: https://github.com/haskell/directory/actions/workflows/build.yml/badge.svg
+[bl]: https://github.com/haskell/directory/actions
+[di]: https://img.shields.io/hackage-deps/v/directory.svg
+[dl]: http://packdeps.haskellers.com/feed?needle=exact:directory
 [ac]: https://gnu.org/software/autoconf
diff --git a/System/Directory.hs b/System/Directory.hs
--- a/System/Directory.hs
+++ b/System/Directory.hs
@@ -1,1948 +1,1352 @@
-{-# LANGUAGE CPP #-}
-
-#if !(MIN_VERSION_base(4,8,0))
--- In base-4.8.0 the Foreign module became Safe
-{-# LANGUAGE Trustworthy #-}
-#endif
-
------------------------------------------------------------------------------
--- |
--- Module      :  System.Directory
--- Copyright   :  (c) The University of Glasgow 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
---
--- Maintainer  :  libraries@haskell.org
--- Stability   :  stable
--- Portability :  portable
---
--- System-independent interface to directory manipulation.
---
------------------------------------------------------------------------------
-
-#include <HsDirectoryConfig.h>
-module System.Directory
-   (
-    -- $intro
-
-    -- * Actions on directories
-      createDirectory
-    , createDirectoryIfMissing
-    , removeDirectory
-    , removeDirectoryRecursive
-    , removePathForcibly
-    , renameDirectory
-    , listDirectory
-    , getDirectoryContents
-    -- ** Current working directory
-    , getCurrentDirectory
-    , setCurrentDirectory
-    , withCurrentDirectory
-
-    -- * Pre-defined directories
-    , getHomeDirectory
-    , XdgDirectory(..)
-    , getXdgDirectory
-    , getAppUserDataDirectory
-    , getUserDocumentsDirectory
-    , getTemporaryDirectory
-
-    -- * Actions on files
-    , removeFile
-    , renameFile
-    , renamePath
-    , copyFile
-    , copyFileWithMetadata
-
-    , canonicalizePath
-    , makeAbsolute
-    , makeRelativeToCurrentDirectory
-    , findExecutable
-    , findExecutables
-    , findExecutablesInDirectories
-    , findFile
-    , findFiles
-    , findFileWith
-    , findFilesWith
-    , exeExtension
-
-    , getFileSize
-
-    -- * Existence tests
-    , doesPathExist
-    , doesFileExist
-    , doesDirectoryExist
-
-    -- * Symbolic links
-    , pathIsSymbolicLink
-
-    -- * Permissions
-
-    -- $permissions
-
-    , Permissions
-    , emptyPermissions
-    , readable
-    , writable
-    , executable
-    , searchable
-    , setOwnerReadable
-    , setOwnerWritable
-    , setOwnerExecutable
-    , setOwnerSearchable
-
-    , getPermissions
-    , setPermissions
-    , copyPermissions
-
-    -- * Timestamps
-
-    , getAccessTime
-    , getModificationTime
-    , setAccessTime
-    , setModificationTime
-
-    -- * Deprecated
-    , isSymbolicLink
-
-   ) where
-import Prelude ()
-import System.Directory.Internal
-import System.Directory.Internal.Prelude
-import System.FilePath
-import Data.Time (UTCTime)
-import Data.Time.Clock.POSIX
-  ( posixSecondsToUTCTime
-  , utcTimeToPOSIXSeconds
-  , POSIXTime
-  )
-#ifdef mingw32_HOST_OS
-import qualified System.Win32 as Win32
-#else
-import qualified GHC.Foreign as GHC
-import qualified System.Posix as Posix
-#endif
-
-{- $intro
-A directory contains a series of entries, each of which is a named
-reference to a file system object (file, directory etc.).  Some
-entries may be hidden, inaccessible, or have some administrative
-function (e.g. @.@ or @..@ under
-<http://www.opengroup.org/onlinepubs/009695399 POSIX>), but in
-this standard all such entries are considered to form part of the
-directory contents. Entries in sub-directories are not, however,
-considered to form part of the directory contents.
-
-Each file system object is referenced by a /path/.  There is
-normally at least one absolute path to each file system object.  In
-some operating systems, it may also be possible to have paths which
-are relative to the current directory.
--}
-
------------------------------------------------------------------------------
--- Permissions
-
-{- $permissions
-
- The 'Permissions' type is used to record whether certain operations are
- permissible on a file\/directory. 'getPermissions' and 'setPermissions'
- get and set these permissions, respectively. Permissions apply both to
- files and directories. For directories, the executable field will be
- 'False', and for files the searchable field will be 'False'. Note that
- directories may be searchable without being readable, if permission has
- been given to use them as part of a path, but not to examine the
- directory contents.
-
-Note that to change some, but not all permissions, a construct on the following lines must be used.
-
->  makeReadable f = do
->     p <- getPermissions f
->     setPermissions f (p {readable = True})
-
--}
-
-data Permissions
- = Permissions {
-    readable,   writable,
-    executable, searchable :: Bool
-   } deriving (Eq, Ord, Read, Show)
-
-emptyPermissions :: Permissions
-emptyPermissions = Permissions {
-                       readable   = False,
-                       writable   = False,
-                       executable = False,
-                       searchable = False
-                   }
-
-setOwnerReadable :: Bool -> Permissions -> Permissions
-setOwnerReadable b p = p { readable = b }
-
-setOwnerWritable :: Bool -> Permissions -> Permissions
-setOwnerWritable b p = p { writable = b }
-
-setOwnerExecutable :: Bool -> Permissions -> Permissions
-setOwnerExecutable b p = p { executable = b }
-
-setOwnerSearchable :: Bool -> Permissions -> Permissions
-setOwnerSearchable b p = p { searchable = b }
-
-{- |The 'getPermissions' operation returns the
-permissions for the file or directory.
-
-The operation may fail with:
-
-* 'isPermissionError' if the user is not permitted to access
-  the permissions; or
-
-* 'isDoesNotExistError' if the file or directory does not exist.
-
--}
-
-getPermissions :: FilePath -> IO Permissions
-getPermissions name =
-#ifdef mingw32_HOST_OS
-  -- issue #9: Windows doesn't like trailing path separators
-  withFilePath (dropTrailingPathSeparator name) $ \s ->
-  -- stat() does a better job of guessing the permissions on Windows
-  -- than access() does.  e.g. for execute permission, it looks at the
-  -- filename extension :-)
-  --
-  -- I tried for a while to do this properly, using the Windows security API,
-  -- and eventually gave up.  getPermissions is a flawed API anyway. -- SimonM
-  allocaBytes sizeof_stat $ \ p_stat -> do
-  throwErrnoIfMinus1_ "getPermissions" $ c_stat s p_stat
-  mode <- st_mode p_stat
-  let usr_read   = mode .&. s_IRUSR
-  let usr_write  = mode .&. s_IWUSR
-  let usr_exec   = mode .&. s_IXUSR
-  let is_dir = mode .&. s_IFDIR
-  return (
-    Permissions {
-      readable   = usr_read  /= 0,
-      writable   = usr_write /= 0,
-      executable = is_dir == 0 && usr_exec /= 0,
-      searchable = is_dir /= 0 && usr_exec /= 0
-    }
-   )
-#else
-  do
-  read_ok  <- Posix.fileAccess name True  False False
-  write_ok <- Posix.fileAccess name False True  False
-  exec_ok  <- Posix.fileAccess name False False True
-  stat <- Posix.getFileStatus name
-  let is_dir = Posix.isDirectory stat
-  return (
-    Permissions {
-      readable   = read_ok,
-      writable   = write_ok,
-      executable = not is_dir && exec_ok,
-      searchable = is_dir && exec_ok
-    }
-   )
-#endif
-
-{- |The 'setPermissions' operation sets the
-permissions for the file or directory.
-
-The operation may fail with:
-
-* 'isPermissionError' if the user is not permitted to set
-  the permissions; or
-
-* 'isDoesNotExistError' if the file or directory does not exist.
-
--}
-
-setPermissions :: FilePath -> Permissions -> IO ()
-setPermissions name (Permissions r w e s) =
-#ifdef mingw32_HOST_OS
-  allocaBytes sizeof_stat $ \ p_stat ->
-  withFilePath name $ \p_name -> do
-    throwErrnoIfMinus1_ "setPermissions" $
-      c_stat p_name p_stat
-
-    throwErrnoIfMinus1_ "setPermissions" $ do
-      mode <- st_mode p_stat
-      let mode1 = modifyBit r mode s_IRUSR
-      let mode2 = modifyBit w mode1 s_IWUSR
-      let mode3 = modifyBit (e || s) mode2 s_IXUSR
-      c_wchmod p_name mode3
- where
-   modifyBit :: Bool -> CMode -> CMode -> CMode
-   modifyBit False m b = m .&. (complement b)
-   modifyBit True  m b = m .|. b
-#else
-  do
-      stat <- Posix.getFileStatus name
-      let mode = Posix.fileMode stat
-      let mode1 = modifyBit r mode  Posix.ownerReadMode
-      let mode2 = modifyBit w mode1 Posix.ownerWriteMode
-      let mode3 = modifyBit (e || s) mode2 Posix.ownerExecuteMode
-      Posix.setFileMode name mode3
- where
-   modifyBit :: Bool -> FileMode -> FileMode -> FileMode
-   modifyBit False m b = m .&. (complement b)
-   modifyBit True  m b = m .|. b
-#endif
-
-copyPermissions :: FilePath -> FilePath -> IO ()
-copyPermissions source dest =
-#ifdef mingw32_HOST_OS
-  allocaBytes sizeof_stat $ \ p_stat ->
-  withFilePath source $ \p_source ->
-  withFilePath dest $ \p_dest -> do
-    throwErrnoIfMinus1_ "copyPermissions" $ c_stat p_source p_stat
-    mode <- st_mode p_stat
-    throwErrnoIfMinus1_ "copyPermissions" $ c_wchmod p_dest mode
-#else
-  do
-  stat <- Posix.getFileStatus source
-  copyPermissionsFromStatus stat dest
-#endif
-
-#ifndef mingw32_HOST_OS
-copyPermissionsFromStatus :: Posix.FileStatus -> FilePath -> IO ()
-copyPermissionsFromStatus st dst = do
-  Posix.setFileMode dst (Posix.fileMode st)
-#endif
-
------------------------------------------------------------------------------
--- Implementation
-
-{- |@'createDirectory' dir@ creates a new directory @dir@ which is
-initially empty, or as near to empty as the operating system
-allows.
-
-The operation may fail with:
-
-* 'isPermissionError' \/ 'PermissionDenied'
-The process has insufficient privileges to perform the operation.
-@[EROFS, EACCES]@
-
-* 'isAlreadyExistsError' \/ 'AlreadyExists'
-The operand refers to a directory that already exists.
-@ [EEXIST]@
-
-* 'HardwareFault'
-A physical I\/O error has occurred.
-@[EIO]@
-
-* 'InvalidArgument'
-The operand is not a valid directory name.
-@[ENAMETOOLONG, ELOOP]@
-
-* 'NoSuchThing'
-There is no path to the directory.
-@[ENOENT, ENOTDIR]@
-
-* 'ResourceExhausted'
-Insufficient resources (virtual memory, process file descriptors,
-physical disk space, etc.) are available to perform the operation.
-@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
-
-* 'InappropriateType'
-The path refers to an existing non-directory object.
-@[EEXIST]@
-
--}
-
-createDirectory :: FilePath -> IO ()
-createDirectory path = do
-#ifdef mingw32_HOST_OS
-  Win32.createDirectory path Nothing
-#else
-  Posix.createDirectory path 0o777
-#endif
-
--- | @'createDirectoryIfMissing' parents dir@ creates a new directory
--- @dir@ if it doesn\'t exist. If the first argument is 'True'
--- the function will also create all parent directories if they are missing.
-createDirectoryIfMissing :: Bool     -- ^ Create its parents too?
-                         -> FilePath -- ^ The path to the directory you want to make
-                         -> IO ()
-createDirectoryIfMissing create_parents path0
-  | create_parents = createDirs (parents path0)
-  | otherwise      = createDirs (take 1 (parents path0))
-  where
-    parents = reverse . scanl1 (</>) . splitDirectories . normalise
-
-    createDirs []         = return ()
-    createDirs (dir:[])   = createDir dir ioError
-    createDirs (dir:dirs) =
-      createDir dir $ \_ -> do
-        createDirs dirs
-        createDir dir ioError
-
-    createDir dir notExistHandler = do
-      r <- tryIOError (createDirectory dir)
-      case r of
-        Right ()                   -> return ()
-        Left  e
-          | isDoesNotExistError  e -> notExistHandler e
-          -- createDirectory (and indeed POSIX mkdir) does not distinguish
-          -- between a dir already existing and a file already existing. So we
-          -- check for it here. Unfortunately there is a slight race condition
-          -- here, but we think it is benign. It could report an exeption in
-          -- the case that the dir did exist but another process deletes the
-          -- directory and creates a file in its place before we can check
-          -- that the directory did indeed exist.
-          -- We also follow this path when we get a permissions error, as
-          -- trying to create "." when in the root directory on Windows
-          -- fails with
-          --     CreateDirectory ".": permission denied (Access is denied.)
-          -- This caused GHCi to crash when loading a module in the root
-          -- directory.
-          | isAlreadyExistsError e
-         || isPermissionError    e -> do
-              canIgnore <- isDir `catchIOError` \ _ ->
-                           return (isAlreadyExistsError e)
-              unless canIgnore (ioError e)
-          | otherwise              -> ioError e
-      where
-#ifdef mingw32_HOST_OS
-        isDir = withFileStatus "createDirectoryIfMissing" dir isDirectory
-#else
-        isDir = (Posix.isDirectory <$> Posix.getFileStatus dir)
-#endif
-
--- | * @'NotDirectory'@:   not a directory.
---   * @'Directory'@:      a true directory (not a symbolic link).
---   * @'DirectoryLink'@:  a directory symbolic link (only exists on Windows).
-data DirectoryType = NotDirectory
-                   | Directory
-                   | DirectoryLink
-                   deriving (Enum, Eq, Ord, Read, Show)
-
--- | Obtain the type of a directory.
-getDirectoryType :: FilePath -> IO DirectoryType
-getDirectoryType path =
-  (`ioeAddLocation` "getDirectoryType") `modifyIOError` do
-#ifdef mingw32_HOST_OS
-    isDir <- withFileStatus "getDirectoryType" path isDirectory
-    if isDir
-      then do
-        isLink <- pathIsSymbolicLink path
-        if isLink
-          then return DirectoryLink
-          else return Directory
-      else do
-        return NotDirectory
-#else
-    stat <- Posix.getSymbolicLinkStatus path
-    return $ if Posix.isDirectory stat
-             then Directory
-             else NotDirectory
-#endif
-
-{- | @'removeDirectory' dir@ removes an existing directory /dir/.  The
-implementation may specify additional constraints which must be
-satisfied before a directory can be removed (e.g. the directory has to
-be empty, or may not be in use by other processes).  It is not legal
-for an implementation to partially remove a directory unless the
-entire directory is removed. A conformant implementation need not
-support directory removal in all situations (e.g. removal of the root
-directory).
-
-The operation may fail with:
-
-* 'HardwareFault'
-A physical I\/O error has occurred.
-@[EIO]@
-
-* 'InvalidArgument'
-The operand is not a valid directory name.
-@[ENAMETOOLONG, ELOOP]@
-
-* 'isDoesNotExistError' \/ 'NoSuchThing'
-The directory does not exist.
-@[ENOENT, ENOTDIR]@
-
-* 'isPermissionError' \/ 'PermissionDenied'
-The process has insufficient privileges to perform the operation.
-@[EROFS, EACCES, EPERM]@
-
-* 'UnsatisfiedConstraints'
-Implementation-dependent constraints are not satisfied.
-@[EBUSY, ENOTEMPTY, EEXIST]@
-
-* 'UnsupportedOperation'
-The implementation does not support removal in this situation.
-@[EINVAL]@
-
-* 'InappropriateType'
-The operand refers to an existing non-directory object.
-@[ENOTDIR]@
-
--}
-
-removeDirectory :: FilePath -> IO ()
-removeDirectory path =
-#ifdef mingw32_HOST_OS
-  Win32.removeDirectory path
-#else
-  Posix.removeDirectory path
-#endif
-
--- | @'removeDirectoryRecursive' dir@ removes an existing directory /dir/
--- together with its contents and subdirectories. Within this directory,
--- symbolic links are removed without affecting their targets.
---
--- On Windows, the operation fails if /dir/ is a directory symbolic link.
-removeDirectoryRecursive :: FilePath -> IO ()
-removeDirectoryRecursive path =
-  (`ioeAddLocation` "removeDirectoryRecursive") `modifyIOError` do
-    dirType <- getDirectoryType path
-    case dirType of
-      Directory ->
-        removeContentsRecursive path
-      DirectoryLink ->
-        ioError (err `ioeSetErrorString` "is a directory symbolic link")
-      NotDirectory ->
-        ioError (err `ioeSetErrorString` "not a directory")
-  where err = mkIOError InappropriateType "" Nothing (Just path)
-
--- | @'removePathRecursive' path@ removes an existing file or directory at
--- /path/ together with its contents and subdirectories. Symbolic links are
--- removed without affecting their the targets.
-removePathRecursive :: FilePath -> IO ()
-removePathRecursive path =
-  (`ioeAddLocation` "removePathRecursive") `modifyIOError` do
-    dirType <- getDirectoryType path
-    case dirType of
-      NotDirectory  -> removeFile path
-      Directory     -> removeContentsRecursive path
-      DirectoryLink -> removeDirectory path
-
--- | @'removeContentsRecursive' dir@ removes the contents of the directory
--- /dir/ recursively. Symbolic links are removed without affecting their the
--- targets.
-removeContentsRecursive :: FilePath -> IO ()
-removeContentsRecursive path =
-  (`ioeAddLocation` "removeContentsRecursive") `modifyIOError` do
-    cont <- listDirectory path
-    mapM_ removePathRecursive [path </> x | x <- cont]
-    removeDirectory path
-
--- | Removes a file or directory at /path/ together with its contents and
--- subdirectories. Symbolic links are removed without affecting their
--- targets. If the path does not exist, nothing happens.
---
--- Unlike other removal functions, this function will also attempt to delete
--- files marked as read-only or otherwise made unremovable due to permissions.
--- As a result, if the removal is incomplete, the permissions or attributes on
--- the remaining files may be altered.
---
--- If an entry within the directory vanishes while @removePathForcibly@ is
--- running, it is silently ignored.
---
--- If an exception occurs while removing an entry, @removePathForcibly@ will
--- still try to remove as many entries as it can before failing with an
--- exception.  The first exception that it encountered is re-thrown.
---
--- @since 1.2.7.0
-removePathForcibly :: FilePath -> IO ()
-removePathForcibly path =
-  (`ioeAddLocation` "removePathForcibly") `modifyIOError` do
-    makeRemovable path `catchIOError` \ _ -> return ()
-    ignoreDoesNotExistError $ do
-      dirType <- getDirectoryType path
-      case dirType of
-        NotDirectory  -> removeFile path
-        DirectoryLink -> removeDirectory path
-        Directory     -> do
-          names <- listDirectory path
-          sequenceWithIOErrors_ $
-            [ removePathForcibly (path </> name) | name <- names ] ++
-            [ removeDirectory path ]
-  where
-
-    ignoreDoesNotExistError :: IO () -> IO ()
-    ignoreDoesNotExistError action = do
-      _ <- tryIOErrorType isDoesNotExistError action
-      return ()
-
-    makeRemovable :: FilePath -> IO ()
-    makeRemovable p = do
-      perms <- getPermissions p
-      setPermissions path perms{ readable = True
-                               , searchable = True
-                               , writable = True }
-
-sequenceWithIOErrors_ :: [IO ()] -> IO ()
-sequenceWithIOErrors_ actions = go (Right ()) actions
-  where
-
-    go :: Either IOError () -> [IO ()] -> IO ()
-    go (Left e)   []       = ioError e
-    go (Right ()) []       = return ()
-    go s          (m : ms) = s `seq` do
-      r <- tryIOError m
-      go (thenEither s r) ms
-
-    -- equivalent to (*>) for Either, defined here to retain compatibility
-    -- with base prior to 4.3
-    thenEither :: Either b a -> Either b a -> Either b a
-    thenEither x@(Left _) _ = x
-    thenEither _          y = y
-
-{- |'removeFile' /file/ removes the directory entry for an existing file
-/file/, where /file/ is not itself a directory. The
-implementation may specify additional constraints which must be
-satisfied before a file can be removed (e.g. the file may not be in
-use by other processes).
-
-The operation may fail with:
-
-* 'HardwareFault'
-A physical I\/O error has occurred.
-@[EIO]@
-
-* 'InvalidArgument'
-The operand is not a valid file name.
-@[ENAMETOOLONG, ELOOP]@
-
-* 'isDoesNotExistError' \/ 'NoSuchThing'
-The file does not exist.
-@[ENOENT, ENOTDIR]@
-
-* 'isPermissionError' \/ 'PermissionDenied'
-The process has insufficient privileges to perform the operation.
-@[EROFS, EACCES, EPERM]@
-
-* 'UnsatisfiedConstraints'
-Implementation-dependent constraints are not satisfied.
-@[EBUSY]@
-
-* 'InappropriateType'
-The operand refers to an existing directory.
-@[EPERM, EINVAL]@
-
--}
-
-removeFile :: FilePath -> IO ()
-removeFile path =
-#ifdef mingw32_HOST_OS
-  Win32.deleteFile path
-#else
-  Posix.removeLink path
-#endif
-
-{- |@'renameDirectory' old new@ changes the name of an existing
-directory from /old/ to /new/.  If the /new/ directory
-already exists, it is atomically replaced by the /old/ directory.
-If the /new/ directory is neither the /old/ directory nor an
-alias of the /old/ directory, it is removed as if by
-'removeDirectory'.  A conformant implementation need not support
-renaming directories in all situations (e.g. renaming to an existing
-directory, or across different physical devices), but the constraints
-must be documented.
-
-On Win32 platforms, @renameDirectory@ fails if the /new/ directory already
-exists.
-
-The operation may fail with:
-
-* 'HardwareFault'
-A physical I\/O error has occurred.
-@[EIO]@
-
-* 'InvalidArgument'
-Either operand is not a valid directory name.
-@[ENAMETOOLONG, ELOOP]@
-
-* 'isDoesNotExistError' \/ 'NoSuchThing'
-The original directory does not exist, or there is no path to the target.
-@[ENOENT, ENOTDIR]@
-
-* 'isPermissionError' \/ 'PermissionDenied'
-The process has insufficient privileges to perform the operation.
-@[EROFS, EACCES, EPERM]@
-
-* 'ResourceExhausted'
-Insufficient resources are available to perform the operation.
-@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
-
-* 'UnsatisfiedConstraints'
-Implementation-dependent constraints are not satisfied.
-@[EBUSY, ENOTEMPTY, EEXIST]@
-
-* 'UnsupportedOperation'
-The implementation does not support renaming in this situation.
-@[EINVAL, EXDEV]@
-
-* 'InappropriateType'
-Either path refers to an existing non-directory object.
-@[ENOTDIR, EISDIR]@
-
--}
-
-renameDirectory :: FilePath -> FilePath -> IO ()
-renameDirectory opath npath =
-   -- XXX this test isn't performed atomically with the following rename
-#ifdef mingw32_HOST_OS
-   -- ToDo: use Win32 API
-   withFileStatus "renameDirectory" opath $ \st -> do
-   is_dir <- isDirectory st
-#else
-   do
-   stat <- Posix.getFileStatus opath
-   let is_dir = Posix.fileMode stat .&. Posix.directoryMode /= 0
-#endif
-   when (not is_dir) $ do
-     ioError . (`ioeSetErrorString` "not a directory") $
-       (mkIOError InappropriateType "renameDirectory" Nothing (Just opath))
-   renamePath opath npath
-
-{- |@'renameFile' old new@ changes the name of an existing file system
-object from /old/ to /new/.  If the /new/ object already
-exists, it is atomically replaced by the /old/ object.  Neither
-path may refer to an existing directory.  A conformant implementation
-need not support renaming files in all situations (e.g. renaming
-across different physical devices), but the constraints must be
-documented.
-
-The operation may fail with:
-
-* 'HardwareFault'
-A physical I\/O error has occurred.
-@[EIO]@
-
-* 'InvalidArgument'
-Either operand is not a valid file name.
-@[ENAMETOOLONG, ELOOP]@
-
-* 'isDoesNotExistError' \/ 'NoSuchThing'
-The original file does not exist, or there is no path to the target.
-@[ENOENT, ENOTDIR]@
-
-* 'isPermissionError' \/ 'PermissionDenied'
-The process has insufficient privileges to perform the operation.
-@[EROFS, EACCES, EPERM]@
-
-* 'ResourceExhausted'
-Insufficient resources are available to perform the operation.
-@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
-
-* 'UnsatisfiedConstraints'
-Implementation-dependent constraints are not satisfied.
-@[EBUSY]@
-
-* 'UnsupportedOperation'
-The implementation does not support renaming in this situation.
-@[EXDEV]@
-
-* 'InappropriateType'
-Either path refers to an existing directory.
-@[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]@
-
--}
-
-renameFile :: FilePath -> FilePath -> IO ()
-renameFile opath npath = (`ioeAddLocation` "renameFile") `modifyIOError` do
-   -- XXX the tests are not performed atomically with the rename
-   checkNotDir opath
-   renamePath opath npath
-     -- The underlying rename implementation can throw odd exceptions when the
-     -- destination is a directory.  For example, Windows typically throws a
-     -- permission error, while POSIX systems may throw a resource busy error
-     -- if one of the paths refers to the current directory.  In these cases,
-     -- we check if the destination is a directory and, if so, throw an
-     -- InappropriateType error.
-     `catchIOError` \ err -> do
-       checkNotDir npath
-       ioError err
-   where checkNotDir path = do
-           dirType <- getDirectoryType path
-                      `catchIOError` \ _ -> return NotDirectory
-           case dirType of
-             Directory     -> errIsDir path
-             DirectoryLink -> errIsDir path
-             NotDirectory  -> return ()
-         errIsDir path = ioError . (`ioeSetErrorString` "is a directory") $
-                         mkIOError InappropriateType "" Nothing (Just path)
-
--- | Rename a file or directory.  If the destination path already exists, it
--- is replaced atomically.  The destination path must not point to an existing
--- directory.  A conformant implementation need not support renaming files in
--- all situations (e.g. renaming across different physical devices), but the
--- constraints must be documented.
---
--- The operation may fail with:
---
--- * 'HardwareFault'
--- A physical I\/O error has occurred.
--- @[EIO]@
---
--- * 'InvalidArgument'
--- Either operand is not a valid file name.
--- @[ENAMETOOLONG, ELOOP]@
---
--- * 'isDoesNotExistError' \/ 'NoSuchThing'
--- The original file does not exist, or there is no path to the target.
--- @[ENOENT, ENOTDIR]@
---
--- * 'isPermissionError' \/ 'PermissionDenied'
--- The process has insufficient privileges to perform the operation.
--- @[EROFS, EACCES, EPERM]@
---
--- * 'ResourceExhausted'
--- Insufficient resources are available to perform the operation.
--- @[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
---
--- * 'UnsatisfiedConstraints'
--- Implementation-dependent constraints are not satisfied.
--- @[EBUSY]@
---
--- * 'UnsupportedOperation'
--- The implementation does not support renaming in this situation.
--- @[EXDEV]@
---
--- * 'InappropriateType'
--- Either the destination path refers to an existing directory, or one of the
--- parent segments in the destination path is not a directory.
--- @[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]@
---
--- @since 1.2.7.0
-renamePath :: FilePath                  -- ^ Old path
-           -> FilePath                  -- ^ New path
-           -> IO ()
-renamePath opath npath = (`ioeAddLocation` "renamePath") `modifyIOError` do
-#ifdef mingw32_HOST_OS
-   Win32.moveFileEx opath npath Win32.mOVEFILE_REPLACE_EXISTING
-#else
-   Posix.rename opath npath
-#endif
-
--- | Copy a file with its permissions.  If the destination file already exists,
--- it is replaced atomically.  Neither path may refer to an existing
--- directory.  No exceptions are thrown if the permissions could not be
--- copied.
-copyFile :: FilePath                    -- ^ Source filename
-         -> FilePath                    -- ^ Destination filename
-         -> IO ()
-copyFile fromFPath toFPath =
-  (`ioeAddLocation` "copyFile") `modifyIOError` do
-    atomicCopyFileContents fromFPath toFPath
-      (ignoreIOExceptions . copyPermissions fromFPath)
-
-#ifndef mingw32_HOST_OS
--- | Truncate the destination file and then copy the contents of the source
--- file to the destination file.  If the destination file already exists, its
--- attributes shall remain unchanged.  Otherwise, its attributes are reset to
--- the defaults.
-copyFileContents :: FilePath            -- ^ Source filename
-                 -> FilePath            -- ^ Destination filename
-                 -> IO ()
-copyFileContents fromFPath toFPath =
-  (`ioeAddLocation` "copyFileContents") `modifyIOError` do
-    withBinaryFile toFPath WriteMode $ \ hTo ->
-      copyFileToHandle fromFPath hTo
-#endif
-
--- | Copy the contents of a source file to a destination file, replacing the
--- destination file atomically via 'withReplacementFile', resetting the
--- attributes of the destination file to the defaults.
-atomicCopyFileContents :: FilePath            -- ^ Source filename
-                       -> FilePath            -- ^ Destination filename
-                       -> (FilePath -> IO ()) -- ^ Post-action
-                       -> IO ()
-atomicCopyFileContents fromFPath toFPath postAction =
-  (`ioeAddLocation` "atomicCopyFileContents") `modifyIOError` do
-    withReplacementFile toFPath postAction $ \ hTo -> do
-      copyFileToHandle fromFPath hTo
-
--- | A helper function useful for replacing files in an atomic manner.  The
--- function creates a temporary file in the directory of the destination file,
--- opens it, performs the main action with its handle, closes it, performs the
--- post-action with its path, and finally replaces the destination file with
--- the temporary file.  If an error occurs during any step of this process,
--- the temporary file is removed and the destination file remains untouched.
-withReplacementFile :: FilePath            -- ^ Destination file
-                    -> (FilePath -> IO ()) -- ^ Post-action
-                    -> (Handle -> IO a)    -- ^ Main action
-                    -> IO a
-withReplacementFile path postAction action =
-  (`ioeAddLocation` "withReplacementFile") `modifyIOError` do
-    mask $ \ restore -> do
-      (tmpFPath, hTmp) <- openBinaryTempFile (takeDirectory path)
-                                             ".copyFile.tmp"
-      (`onException` ignoreIOExceptions (removeFile tmpFPath)) $ do
-        r <- (`onException` ignoreIOExceptions (hClose hTmp)) $ do
-          restore (action hTmp)
-        hClose hTmp
-        restore (postAction tmpFPath)
-        renameFile tmpFPath path
-        return r
-
--- | Attempt to perform the given action, silencing any IO exception thrown by
--- it.
-ignoreIOExceptions :: IO () -> IO ()
-ignoreIOExceptions io = io `catchIOError` (\_ -> return ())
-
--- | Copy all data from a file to a handle.
-copyFileToHandle :: FilePath            -- ^ Source file
-                 -> Handle              -- ^ Destination handle
-                 -> IO ()
-copyFileToHandle fromFPath hTo =
-  (`ioeAddLocation` "copyFileToHandle") `modifyIOError` do
-    withBinaryFile fromFPath ReadMode $ \ hFrom ->
-      copyHandleData hFrom hTo
-
--- | Copy data from one handle to another until end of file.
-copyHandleData :: Handle                -- ^ Source handle
-               -> Handle                -- ^ Destination handle
-               -> IO ()
-copyHandleData hFrom hTo =
-  (`ioeAddLocation` "copyData") `modifyIOError` do
-    allocaBytes bufferSize go
-  where
-    bufferSize = 1024
-    go buffer = do
-      count <- hGetBuf hFrom buffer bufferSize
-      when (count > 0) $ do
-        hPutBuf hTo buffer count
-        go buffer
-
--- | Copy a file with its associated metadata.  If the destination file
--- already exists, it is overwritten.  There is no guarantee of atomicity in
--- the replacement of the destination file.  Neither path may refer to an
--- existing directory.  If the source and/or destination are symbolic links,
--- the copy is performed on the targets of the links.
---
--- On Windows, it behaves like the Win32 function
--- <https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851.aspx CopyFile>,
--- which copies various kinds of metadata including file attributes and
--- security resource properties.
---
--- On Unix-like systems, permissions, access time, and modification time are
--- preserved.  If possible, the owner and group are also preserved.  Note that
--- the very act of copying can change the access time of the source file,
--- hence the access times of the two files may differ after the operation
--- completes.
---
--- @since 1.2.6.0
-copyFileWithMetadata :: FilePath        -- ^ Source file
-                     -> FilePath        -- ^ Destination file
-                     -> IO ()
-copyFileWithMetadata src dst =
-  (`ioeAddLocation` "copyFileWithMetadata") `modifyIOError` doCopy
-  where
-#ifdef mingw32_HOST_OS
-    doCopy = Win32.copyFile src dst False
-#else
-    doCopy = do
-      st <- Posix.getFileStatus src
-      copyFileContents src dst
-      copyMetadataFromStatus st dst
-#endif
-
-#ifndef mingw32_HOST_OS
-copyMetadataFromStatus :: Posix.FileStatus -> FilePath -> IO ()
-copyMetadataFromStatus st dst = do
-  tryCopyOwnerAndGroupFromStatus st dst
-  copyPermissionsFromStatus st dst
-  copyFileTimesFromStatus st dst
-#endif
-
-#ifndef mingw32_HOST_OS
-tryCopyOwnerAndGroupFromStatus :: Posix.FileStatus -> FilePath -> IO ()
-tryCopyOwnerAndGroupFromStatus st dst = do
-  ignoreIOExceptions (copyOwnerFromStatus st dst)
-  ignoreIOExceptions (copyGroupFromStatus st dst)
-#endif
-
-#ifndef mingw32_HOST_OS
-copyOwnerFromStatus :: Posix.FileStatus -> FilePath -> IO ()
-copyOwnerFromStatus st dst = do
-  Posix.setOwnerAndGroup dst (Posix.fileOwner st) (-1)
-#endif
-
-#ifndef mingw32_HOST_OS
-copyGroupFromStatus :: Posix.FileStatus -> FilePath -> IO ()
-copyGroupFromStatus st dst = do
-  Posix.setOwnerAndGroup dst (-1) (Posix.fileGroup st)
-#endif
-
-#ifndef mingw32_HOST_OS
-copyFileTimesFromStatus :: Posix.FileStatus -> FilePath -> IO ()
-copyFileTimesFromStatus st dst = do
-  let (atime, mtime) = fileTimesFromStatus st
-  setFileTimes dst (Just atime, Just mtime)
-#endif
-
--- | Make a path absolute, 'normalise' the path, and remove as many
--- indirections from it as possible.  Any trailing path separators are
--- discarded via 'dropTrailingPathSeparator'.  Additionally, on Windows the
--- letter case of the path is canonicalized.
---
--- __Note__: This function is a very big hammer.  If you only need an absolute
--- path, 'makeAbsolute' is sufficient for removing dependence on the current
--- working directory.
---
--- Indirections include the two special directories @.@ and @..@, as well as
--- any symbolic links.  The input path need not point to an existing file or
--- directory.  Canonicalization is performed on the longest prefix of the path
--- that points to an existing file or directory.  The remaining portion of the
--- path that does not point to an existing file or directory will still
--- undergo 'normalise', but case canonicalization and indirection removal are
--- skipped as they are impossible to do on a nonexistent path.
---
--- Most programs should not worry about the canonicity of a path.  In
--- particular, despite the name, the function does not truly guarantee
--- canonicity of the returned path due to the presence of hard links, mount
--- points, etc.
---
--- If the path points to an existing file or directory, then the output path
--- shall also point to the same file or directory, subject to the condition
--- that the relevant parts of the file system do not change while the function
--- is still running.  In other words, the function is definitively not atomic.
--- The results can be utterly wrong if the portions of the path change while
--- this function is running.
---
--- Since symbolic links (and, on non-Windows systems, parent directories @..@)
--- are dependent on the state of the existing filesystem, the function can
--- only make a conservative attempt by removing such indirections from the
--- longest prefix of the path that still points to an existing file or
--- directory.
---
--- Note that on Windows parent directories @..@ are always fully expanded
--- before the symbolic links, as consistent with the rest of the Windows API
--- (such as @GetFullPathName@).  In contrast, on POSIX systems parent
--- directories @..@ are expanded alongside symbolic links from left to right.
--- To put this more concretely: if @L@ is a symbolic link for @R/P@, then on
--- Windows @L\\..@ refers to @.@, whereas on other operating systems @L/..@
--- refers to @R@.
---
--- Similar to 'normalise', passing an empty path is equivalent to passing the
--- current directory.
---
--- /Known bugs/: When the path contains an existing symbolic link, but the
--- target of the link does not exist, then the path is not dereferenced (bug
--- #64).  Symbolic link expansion is not performed on Windows XP or earlier
--- due to the absence of @GetFinalPathNameByHandle@.
---
--- /Changes since 1.2.3.0:/ The function has been altered to be more robust
--- and has the same exception behavior as 'makeAbsolute'.
---
--- /Changes since 1.3.0.0:/ The function no longer preserves the trailing path
--- separator.  File symbolic links that appear in the middle of a path are
--- properly dereferenced.  Case canonicalization and symbolic link expansion
--- are now performed on Windows.
---
-canonicalizePath :: FilePath -> IO FilePath
-canonicalizePath = \ path ->
-  modifyIOError ((`ioeAddLocation` "canonicalizePath") .
-                 (`ioeSetFileName` path)) $
-  -- normalise does more stuff, like upper-casing the drive letter
-  dropTrailingPathSeparator . normalise <$>
-    (transform =<< prependCurrentDirectory path)
-  where
-
-#if defined(mingw32_HOST_OS)
-    transform path =
-      attemptRealpath getFinalPathName =<<
-        (Win32.getFullPathName path `catchIOError` \ _ -> return path)
-#else
-    transform path = do
-      encoding <- getFileSystemEncoding
-      let realpath path' =
-            GHC.withCString encoding path'
-              (`withRealpath` GHC.peekCString encoding)
-      attemptRealpath realpath path
-#endif
-
-    attemptRealpath realpath path =
-      realpathPrefix realpath (reverse (zip prefixes suffixes)) path
-      where segments = splitDirectories path
-            prefixes = scanl1 (</>) segments
-            suffixes = tail (scanr (</>) "" segments)
-
-    -- call realpath on the largest possible prefix
-    realpathPrefix realpath ((prefix, suffix) : rest) path = do
-      exist <- doesPathExist prefix
-      if exist -- never call realpath on an inaccessible path
-        then ((</> suffix) <$> realpath prefix)
-             `catchIOError` \ _ -> realpathPrefix realpath rest path
-        else realpathPrefix realpath rest path
-    realpathPrefix _ _ path = return path
-
--- | Convert a path into an absolute path.  If the given path is relative, the
--- current directory is prepended and then the combined result is
--- 'normalise'd.  If the path is already absolute, the path is simply
--- 'normalise'd.  The function preserves the presence or absence of the
--- trailing path separator unless the path refers to the root directory @/@.
---
--- If the path is already absolute, the operation never fails.  Otherwise, the
--- operation may fail with the same exceptions as 'getCurrentDirectory'.
---
--- @since 1.2.2.0
---
-makeAbsolute :: FilePath -> IO FilePath
-makeAbsolute path =
-  modifyIOError ((`ioeAddLocation` "makeAbsolute") .
-                 (`ioeSetFileName` path)) $
-  matchTrailingSeparator path . normalise <$> prependCurrentDirectory path
-
--- | Convert a path into an absolute path.  If the given path is relative, the
--- current directory is prepended.  If the path is already absolute, the path
--- is returned unchanged.  The function preserves the presence or absence of
--- the trailing path separator.
---
--- If the path is already absolute, the operation never fails.  Otherwise, the
--- operation may fail with the same exceptions as 'getCurrentDirectory'.
---
--- (internal API)
-prependCurrentDirectory :: FilePath -> IO FilePath
-prependCurrentDirectory path =
-  modifyIOError ((`ioeAddLocation` "prependCurrentDirectory") .
-                 (`ioeSetFileName` path)) $
-  if isRelative path -- avoid the call to `getCurrentDirectory` if we can
-  then (</> path) <$> getCurrentDirectory
-  else return path
-
--- | Add or remove the trailing path separator in the second path so as to
--- match its presence in the first path.
---
--- (internal API)
-matchTrailingSeparator :: FilePath -> FilePath -> FilePath
-matchTrailingSeparator path
-  | hasTrailingPathSeparator path = addTrailingPathSeparator
-  | otherwise                     = dropTrailingPathSeparator
-
--- | Construct a path relative to the current directory, similar to
--- 'makeRelative'.
---
--- The operation may fail with the same exceptions as 'getCurrentDirectory'.
-makeRelativeToCurrentDirectory :: FilePath -> IO FilePath
-makeRelativeToCurrentDirectory x = do
-    cur <- getCurrentDirectory
-    return $ makeRelative cur x
-
--- | Given an executable file name, searches for such file in the
--- directories listed in system PATH. The returned value is the path
--- to the found executable or Nothing if an executable with the given
--- name was not found. For example (findExecutable \"ghc\") gives you
--- the path to GHC.
---
--- The path returned by 'findExecutable' corresponds to the
--- program that would be executed by 'System.Process.createProcess'
--- when passed the same string (as a RawCommand, not a ShellCommand).
---
--- On Windows, 'findExecutable' calls the Win32 function 'SearchPath',
--- which may search other places before checking the directories in
--- @PATH@.  Where it actually searches depends on registry settings,
--- but notably includes the directory containing the current
--- executable. See
--- <http://msdn.microsoft.com/en-us/library/aa365527.aspx> for more
--- details.
---
-findExecutable :: String -> IO (Maybe FilePath)
-findExecutable binary = do
-#if defined(mingw32_HOST_OS)
-    Win32.searchPath Nothing binary exeExtension
-#else
-    path <- getPath
-    findFileWith isExecutable path (binary <.> exeExtension)
-#endif
-
--- | Given a file name, searches for the file and returns a list of all
--- occurences that are executable.
---
--- On Windows, this only returns the first ocurrence, if any.  It uses the
--- @SearchPath@ from the Win32 API, so the caveats noted in 'findExecutable'
--- apply here as well.
---
--- @since 1.2.2.0
-findExecutables :: String -> IO [FilePath]
-findExecutables binary = do
-#if defined(mingw32_HOST_OS)
-    file <- findExecutable binary
-    return $ maybeToList file
-#else
-    path <- getPath
-    findExecutablesInDirectories path binary
-#endif
-
-#ifndef mingw32_HOST_OS
--- | Get the contents of the @PATH@ environment variable.
-getPath :: IO [FilePath]
-getPath = do
-    path <- getEnv "PATH"
-    return (splitSearchPath path)
-#endif
-
--- | Given a file name, searches for the file on the given paths and returns a
--- list of all occurences that are executable.
---
--- @since 1.2.4.0
-findExecutablesInDirectories :: [FilePath] -> String -> IO [FilePath]
-findExecutablesInDirectories path binary =
-    findFilesWith isExecutable path (binary <.> exeExtension)
-
--- | Test whether a file is executable.
-isExecutable :: FilePath -> IO Bool
-isExecutable file = do
-    perms <- getPermissions file
-    return (executable perms)
-
--- | Search through the given set of directories for the given file.
-findFile :: [FilePath] -> String -> IO (Maybe FilePath)
-findFile = findFileWith (\_ -> return True)
-
--- | Search through the given set of directories for the given file and
--- returns a list of paths where the given file exists.
---
--- @since 1.2.1.0
-findFiles :: [FilePath] -> String -> IO [FilePath]
-findFiles = findFilesWith (\_ -> return True)
-
--- | Search through the given set of directories for the given file and
--- with the given property (usually permissions) and returns the file path
--- where the given file exists and has the property.
---
--- @since 1.2.6.0
-findFileWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO (Maybe FilePath)
-findFileWith f ds name = asumMaybeT (map (findFileWithIn f name) ds)
-
--- | 'Data.Foldable.asum' for 'Control.Monad.Trans.Maybe.MaybeT', essentially.
---
--- Returns the first 'Just' in the list or 'Nothing' if there aren't any.
-asumMaybeT :: Monad m => [m (Maybe a)] -> m (Maybe a)
-asumMaybeT = foldr attempt (return Nothing)
-  where
-    attempt mmx mx' = do
-        mx <- mmx
-        case mx of
-            Nothing -> mx'
-            Just _  -> return mx
-
--- | Search through the given set of directories for the given file and
--- with the given property (usually permissions) and returns a list of
--- paths where the given file exists and has the property.
---
--- @since 1.2.1.0
-findFilesWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO [FilePath]
-findFilesWith f ds name = do
-    mfiles <- mapM (findFileWithIn f name) ds
-    return (catMaybes mfiles)
-
--- | Like 'findFileWith', but searches only a single directory.
-findFileWithIn :: (FilePath -> IO Bool) -> String -> FilePath -> IO (Maybe FilePath)
-findFileWithIn f name d = do
-    let path = d </> name
-    exist <- doesFileExist path
-    if exist
-        then do
-            ok <- f path
-            if ok
-                then return (Just path)
-                else return Nothing
-        else return Nothing
-
--- | Similar to 'listDirectory', but always includes the special entries (@.@
--- and @..@).  (This applies to Windows as well.)
---
--- The operation may fail with the same exceptions as 'listDirectory'.
-getDirectoryContents :: FilePath -> IO [FilePath]
-getDirectoryContents path =
-  modifyIOError ((`ioeSetFileName` path) .
-                 (`ioeAddLocation` "getDirectoryContents")) $ do
-#ifndef mingw32_HOST_OS
-    bracket
-      (Posix.openDirStream path)
-      Posix.closeDirStream
-      start
- where
-  start dirp =
-      loop id
-    where
-      loop acc = do
-        e <- Posix.readDirStream dirp
-        if null e
-          then return (acc [])
-          else loop (acc . (e:))
-#else
-  bracket
-     (Win32.findFirstFile (path </> "*"))
-     (\(h,_) -> Win32.findClose h)
-     (\(h,fdat) -> loop h fdat [])
-  where
-        -- we needn't worry about empty directories: adirectory always
-        -- has at least "." and ".." entries
-    loop :: Win32.HANDLE -> Win32.FindData -> [FilePath] -> IO [FilePath]
-    loop h fdat acc = do
-       filename <- Win32.getFindDataFileName fdat
-       more <- Win32.findNextFile h fdat
-       if more
-          then loop h fdat (filename:acc)
-          else return (filename:acc)
-                 -- no need to reverse, ordering is undefined
-#endif /* mingw32 */
-
--- | @'listDirectory' dir@ returns a list of /all/ entries in /dir/ without
--- the special entries (@.@ and @..@).
---
--- The operation may fail with:
---
--- * 'HardwareFault'
---   A physical I\/O error has occurred.
---   @[EIO]@
---
--- * 'InvalidArgument'
---   The operand is not a valid directory name.
---   @[ENAMETOOLONG, ELOOP]@
---
--- * 'isDoesNotExistError' \/ 'NoSuchThing'
---   The directory does not exist.
---   @[ENOENT, ENOTDIR]@
---
--- * 'isPermissionError' \/ 'PermissionDenied'
---   The process has insufficient privileges to perform the operation.
---   @[EACCES]@
---
--- * 'ResourceExhausted'
---   Insufficient resources are available to perform the operation.
---   @[EMFILE, ENFILE]@
---
--- * 'InappropriateType'
---   The path refers to an existing non-directory object.
---   @[ENOTDIR]@
---
--- @since 1.2.5.0
---
-listDirectory :: FilePath -> IO [FilePath]
-listDirectory path =
-  (filter f) <$> (getDirectoryContents path)
-  where f filename = filename /= "." && filename /= ".."
-
--- | Obtain the current working directory as an absolute path.
---
--- In a multithreaded program, the current working directory is a global state
--- shared among all threads of the process.  Therefore, when performing
--- filesystem operations from multiple threads, it is highly recommended to
--- use absolute rather than relative paths (see: 'makeAbsolute').
---
--- The operation may fail with:
---
--- * 'HardwareFault'
--- A physical I\/O error has occurred.
--- @[EIO]@
---
--- * 'isDoesNotExistError' or 'NoSuchThing'
--- There is no path referring to the working directory.
--- @[EPERM, ENOENT, ESTALE...]@
---
--- * 'isPermissionError' or 'PermissionDenied'
--- The process has insufficient privileges to perform the operation.
--- @[EACCES]@
---
--- * 'ResourceExhausted'
--- Insufficient resources are available to perform the operation.
---
--- * 'UnsupportedOperation'
--- The operating system has no notion of current working directory.
---
-getCurrentDirectory :: IO FilePath
-getCurrentDirectory =
-  modifyIOError (`ioeAddLocation` "getCurrentDirectory") $
-  specializeErrorString
-    "Current working directory no longer exists"
-    isDoesNotExistError
-    getCwd
-  where
-#ifdef mingw32_HOST_OS
-    getCwd = Win32.getCurrentDirectory
-#else
-    getCwd = Posix.getWorkingDirectory
-#endif
-
--- | Change the working directory to the given path.
---
--- In a multithreaded program, the current working directory is a global state
--- shared among all threads of the process.  Therefore, when performing
--- filesystem operations from multiple threads, it is highly recommended to
--- use absolute rather than relative paths (see: 'makeAbsolute').
---
--- The operation may fail with:
---
--- * 'HardwareFault'
--- A physical I\/O error has occurred.
--- @[EIO]@
---
--- * 'InvalidArgument'
--- The operand is not a valid directory name.
--- @[ENAMETOOLONG, ELOOP]@
---
--- * 'isDoesNotExistError' or 'NoSuchThing'
--- The directory does not exist.
--- @[ENOENT, ENOTDIR]@
---
--- * 'isPermissionError' or 'PermissionDenied'
--- The process has insufficient privileges to perform the operation.
--- @[EACCES]@
---
--- * 'UnsupportedOperation'
--- The operating system has no notion of current working directory, or the
--- working directory cannot be dynamically changed.
---
--- * 'InappropriateType'
--- The path refers to an existing non-directory object.
--- @[ENOTDIR]@
---
-setCurrentDirectory :: FilePath -> IO ()
-setCurrentDirectory =
-#ifdef mingw32_HOST_OS
-  Win32.setCurrentDirectory
-#else
-  Posix.changeWorkingDirectory
-#endif
-
--- | Run an 'IO' action with the given working directory and restore the
--- original working directory afterwards, even if the given action fails due
--- to an exception.
---
--- The operation may fail with the same exceptions as 'getCurrentDirectory'
--- and 'setCurrentDirectory'.
---
--- @since 1.2.3.0
---
-withCurrentDirectory :: FilePath  -- ^ Directory to execute in
-                     -> IO a      -- ^ Action to be executed
-                     -> IO a
-withCurrentDirectory dir action =
-  bracket getCurrentDirectory setCurrentDirectory $ \ _ -> do
-    setCurrentDirectory dir
-    action
-
--- | Obtain the size of a file in bytes.
---
--- @since 1.2.7.0
-getFileSize :: FilePath -> IO Integer
-getFileSize path =
-  (`ioeAddLocation` "getFileSize") `modifyIOError` do
-#ifdef mingw32_HOST_OS
-    fromIntegral <$> withFileStatus "" path st_size
-#else
-    fromIntegral . Posix.fileSize <$> Posix.getFileStatus path
-#endif
-
--- | Test whether the given path points to an existing filesystem object.  If
--- the user lacks necessary permissions to search the parent directories, this
--- function may return false even if the file does actually exist.
---
--- @since 1.2.7.0
-doesPathExist :: FilePath -> IO Bool
-doesPathExist path =
-#ifdef mingw32_HOST_OS
-  (withFileStatus "" path $ \ _ -> return True)
-#else
-  (Posix.getFileStatus path >> return True)
-#endif
-  `catchIOError` \ _ -> return False
-
-{- |The operation 'doesDirectoryExist' returns 'True' if the argument file
-exists and is either a directory or a symbolic link to a directory,
-and 'False' otherwise.
--}
-
-doesDirectoryExist :: FilePath -> IO Bool
-doesDirectoryExist name =
-#ifdef mingw32_HOST_OS
-   (withFileStatus "doesDirectoryExist" name $ \st -> isDirectory st)
-#else
-   (do stat <- Posix.getFileStatus name
-       return (Posix.isDirectory stat))
-#endif
-   `catchIOError` \ _ -> return False
-
-{- |The operation 'doesFileExist' returns 'True'
-if the argument file exists and is not a directory, and 'False' otherwise.
--}
-
-doesFileExist :: FilePath -> IO Bool
-doesFileExist name =
-#ifdef mingw32_HOST_OS
-   (withFileStatus "doesFileExist" name $ \st -> do b <- isDirectory st; return (not b))
-#else
-   (do stat <- Posix.getFileStatus name
-       return (not (Posix.isDirectory stat)))
-#endif
-   `catchIOError` \ _ -> return False
-
--- | Check whether the path refers to a symbolic link.  On Windows, this tests
--- for @FILE_ATTRIBUTE_REPARSE_POINT@.
---
--- @since 1.3.0.0
-pathIsSymbolicLink :: FilePath -> IO Bool
-pathIsSymbolicLink path =
-  (`ioeAddLocation` "getDirectoryType") `modifyIOError` do
-#ifdef mingw32_HOST_OS
-    isReparsePoint <$> Win32.getFileAttributes path
-  where
-    isReparsePoint attr = attr .&. win32_fILE_ATTRIBUTE_REPARSE_POINT /= 0
-#else
-    Posix.isSymbolicLink <$> Posix.getSymbolicLinkStatus path
-#endif
-
-{-# DEPRECATED isSymbolicLink "Use 'pathIsSymbolicLink' instead" #-}
-isSymbolicLink :: FilePath -> IO Bool
-isSymbolicLink = pathIsSymbolicLink
-
-#ifdef mingw32_HOST_OS
--- | Open the handle of an existing file or directory.
-openFileHandle :: String -> Win32.AccessMode -> IO Win32.HANDLE
-openFileHandle path mode = Win32.createFile path mode share Nothing
-                                            Win32.oPEN_EXISTING flags Nothing
-  where share =  win32_fILE_SHARE_DELETE
-             .|. Win32.fILE_SHARE_READ
-             .|. Win32.fILE_SHARE_WRITE
-        flags =  Win32.fILE_ATTRIBUTE_NORMAL
-             .|. Win32.fILE_FLAG_BACKUP_SEMANTICS -- required for directories
-#endif
-
--- | Obtain the time at which the file or directory was last accessed.
---
--- The operation may fail with:
---
--- * 'isPermissionError' if the user is not permitted to read
---   the access time; or
---
--- * 'isDoesNotExistError' if the file or directory does not exist.
---
--- Caveat for POSIX systems: This function returns a timestamp with sub-second
--- resolution only if this package is compiled against @unix-2.6.0.0@ or later
--- and the underlying filesystem supports them.
---
--- @since 1.2.3.0
---
-getAccessTime :: FilePath -> IO UTCTime
-getAccessTime = modifyIOError (`ioeAddLocation` "getAccessTime") .
-                (fst <$>) . getFileTimes
-
--- | Obtain the time at which the file or directory was last modified.
---
--- The operation may fail with:
---
--- * 'isPermissionError' if the user is not permitted to read
---   the modification time; or
---
--- * 'isDoesNotExistError' if the file or directory does not exist.
---
--- Caveat for POSIX systems: This function returns a timestamp with sub-second
--- resolution only if this package is compiled against @unix-2.6.0.0@ or later
--- and the underlying filesystem supports them.
---
-getModificationTime :: FilePath -> IO UTCTime
-getModificationTime = modifyIOError (`ioeAddLocation` "getModificationTime") .
-                      (snd <$>) . getFileTimes
-
-getFileTimes :: FilePath -> IO (UTCTime, UTCTime)
-getFileTimes path =
-  modifyIOError (`ioeAddLocation` "getFileTimes") .
-  modifyIOError (`ioeSetFileName` path) $
-    getTimes
-  where
-    path' = normalise path              -- handle empty paths
-#ifdef mingw32_HOST_OS
-    getTimes =
-      bracket (openFileHandle path' Win32.gENERIC_READ)
-              Win32.closeHandle $ \ handle ->
-      alloca $ \ atime ->
-      alloca $ \ mtime -> do
-        Win32.failIf_ not "" $
-          Win32.c_GetFileTime handle nullPtr atime mtime
-        ((,) `on` posixSecondsToUTCTime . windowsToPosixTime)
-          <$> peek atime
-          <*> peek mtime
-#else
-    getTimes = fileTimesFromStatus <$> Posix.getFileStatus path'
-#endif
-
-#ifndef mingw32_HOST_OS
-fileTimesFromStatus :: Posix.FileStatus -> (UTCTime, UTCTime)
-fileTimesFromStatus st =
-# if MIN_VERSION_unix(2, 6, 0)
-  ( posixSecondsToUTCTime (Posix.accessTimeHiRes st)
-  , posixSecondsToUTCTime (Posix.modificationTimeHiRes st) )
-# else
-  ( posixSecondsToUTCTime (realToFrac (Posix.accessTime st))
-  , posixSecondsToUTCTime (realToFrac (Posix.modificationTime st)) )
-# endif
-#endif
-
--- | Change the time at which the file or directory was last accessed.
---
--- The operation may fail with:
---
--- * 'isPermissionError' if the user is not permitted to alter the
---   access time; or
---
--- * 'isDoesNotExistError' if the file or directory does not exist.
---
--- Some caveats for POSIX systems:
---
--- * Not all systems support @utimensat@, in which case the function can only
---   emulate the behavior by reading the modification time and then setting
---   both the access and modification times together.  On systems where
---   @utimensat@ is supported, the access time is set atomically with
---   nanosecond precision.
---
--- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function
---   would not be able to set timestamps with sub-second resolution.  In this
---   case, there would also be loss of precision in the modification time.
---
--- @since 1.2.3.0
---
-setAccessTime :: FilePath -> UTCTime -> IO ()
-setAccessTime path atime =
-  modifyIOError (`ioeAddLocation` "setAccessTime") $
-    setFileTimes path (Just atime, Nothing)
-
--- | Change the time at which the file or directory was last modified.
---
--- The operation may fail with:
---
--- * 'isPermissionError' if the user is not permitted to alter the
---   modification time; or
---
--- * 'isDoesNotExistError' if the file or directory does not exist.
---
--- Some caveats for POSIX systems:
---
--- * Not all systems support @utimensat@, in which case the function can only
---   emulate the behavior by reading the access time and then setting both the
---   access and modification times together.  On systems where @utimensat@ is
---   supported, the modification time is set atomically with nanosecond
---   precision.
---
--- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function
---   would not be able to set timestamps with sub-second resolution.  In this
---   case, there would also be loss of precision in the access time.
---
--- @since 1.2.3.0
---
-setModificationTime :: FilePath -> UTCTime -> IO ()
-setModificationTime path mtime =
-  modifyIOError (`ioeAddLocation` "setModificationTime") $
-    setFileTimes path (Nothing, Just mtime)
-
-setFileTimes :: FilePath -> (Maybe UTCTime, Maybe UTCTime) -> IO ()
-setFileTimes _ (Nothing, Nothing) = return ()
-setFileTimes path (atime, mtime) =
-  modifyIOError (`ioeAddLocation` "setFileTimes") .
-  modifyIOError (`ioeSetFileName` path) $
-    setTimes (utcTimeToPOSIXSeconds <$> atime, utcTimeToPOSIXSeconds <$> mtime)
-  where
-    path' = normalise path              -- handle empty paths
-
-    setTimes :: (Maybe POSIXTime, Maybe POSIXTime) -> IO ()
-#ifdef mingw32_HOST_OS
-    setTimes (atime', mtime') =
-      bracket (openFileHandle path' Win32.gENERIC_WRITE)
-              Win32.closeHandle $ \ handle ->
-      maybeWith with (posixToWindowsTime <$> atime') $ \ atime'' ->
-      maybeWith with (posixToWindowsTime <$> mtime') $ \ mtime'' ->
-      Win32.failIf_ not "" $
-        Win32.c_SetFileTime handle nullPtr atime'' mtime''
-#elif defined HAVE_UTIMENSAT
-    setTimes (atime', mtime') =
-      withFilePath path' $ \ path'' ->
-      withArray [ maybe utimeOmit toCTimeSpec atime'
-                , maybe utimeOmit toCTimeSpec mtime' ] $ \ times ->
-      throwErrnoPathIfMinus1_ "" path' $
-        c_utimensat c_AT_FDCWD path'' times 0
-#else
-    setTimes (Just atime', Just mtime') = setFileTimes' path' atime' mtime'
-    setTimes (atime', mtime') = do
-      (atimeOld, mtimeOld) <- fileTimesFromStatus <$> Posix.getFileStatus path'
-      setFileTimes' path'
-        (fromMaybe (utcTimeToPOSIXSeconds atimeOld) atime')
-        (fromMaybe (utcTimeToPOSIXSeconds mtimeOld) mtime')
-
-    setFileTimes' :: FilePath -> POSIXTime -> POSIXTime -> IO ()
-# if MIN_VERSION_unix(2, 7, 0)
-    setFileTimes' = Posix.setFileTimesHiRes
-#  else
-    setFileTimes' pth atime' mtime' =
-      Posix.setFileTimes pth
-        (fromInteger (truncate atime'))
-        (fromInteger (truncate mtime'))
-# endif
-#endif
-
-#ifdef mingw32_HOST_OS
--- | Difference between the Windows and POSIX epochs in units of 100ns.
-windowsPosixEpochDifference :: Num a => a
-windowsPosixEpochDifference = 116444736000000000
-
--- | Convert from Windows time to POSIX time.
-windowsToPosixTime :: Win32.FILETIME -> POSIXTime
-windowsToPosixTime (Win32.FILETIME t) =
-  (fromIntegral t - windowsPosixEpochDifference) / 10000000
-
--- | Convert from POSIX time to Windows time.  This is lossy as Windows time
---   has a resolution of only 100ns.
-posixToWindowsTime :: POSIXTime -> Win32.FILETIME
-posixToWindowsTime t = Win32.FILETIME $
-  truncate (t * 10000000 + windowsPosixEpochDifference)
-#endif
-
-#ifdef mingw32_HOST_OS
-withFileStatus :: String -> FilePath -> (Ptr CStat -> IO a) -> IO a
-withFileStatus loc name f = do
-  modifyIOError (`ioeSetFileName` name) $
-    allocaBytes sizeof_stat $ \p ->
-      withFilePath (fileNameEndClean name) $ \s -> do
-        throwErrnoIfMinus1Retry_ loc (c_stat s p)
-        f p
-
-isDirectory :: Ptr CStat -> IO Bool
-isDirectory stat = do
-  mode <- st_mode stat
-  return (s_isdir mode)
-
-fileNameEndClean :: String -> String
-fileNameEndClean name = if isDrive name then addTrailingPathSeparator name
-                                        else dropTrailingPathSeparator name
-#endif
-
-{- | Returns the current user's home directory.
-
-The directory returned is expected to be writable by the current user,
-but note that it isn't generally considered good practice to store
-application-specific data here; use 'getXdgDirectory' or
-'getAppUserDataDirectory' instead.
-
-On Unix, 'getHomeDirectory' returns the value of the @HOME@
-environment variable.  On Windows, the system is queried for a
-suitable path; a typical path might be @C:\/Users\//\<user\>/@.
-
-The operation may fail with:
-
-* 'UnsupportedOperation'
-The operating system has no notion of home directory.
-
-* 'isDoesNotExistError'
-The home directory for the current user does not exist, or
-cannot be found.
--}
-getHomeDirectory :: IO FilePath
-getHomeDirectory = modifyIOError (`ioeAddLocation` "getHomeDirectory") get
-  where
-#if defined(mingw32_HOST_OS)
-    get = getFolderPath Win32.cSIDL_PROFILE `catchIOError` \ _ ->
-          getFolderPath Win32.cSIDL_WINDOWS
-    getFolderPath what = Win32.sHGetFolderPath nullPtr what nullPtr 0
-#else
-    get = getEnv "HOME"
-#endif
-
--- | Special directories for storing user-specific application data,
---   configuration, and cache files, as specified by the
---   <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
---
---   Note: On Windows, 'XdgData' and 'XdgConfig' map to the same directory.
---
---   @since 1.2.3.0
-data XdgDirectory
-  = XdgData
-    -- ^ For data files (e.g. images).
-    --   Defaults to @~\/.local\/share@ and can be
-    --   overridden by the @XDG_DATA_HOME@ environment variable.
-    --   On Windows, it is @%APPDATA%@
-    --   (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).
-    --   Can be considered as the user-specific equivalent of @\/usr\/share@.
-  | XdgConfig
-    -- ^ For configuration files.
-    --   Defaults to @~\/.config@ and can be
-    --   overridden by the @XDG_CONFIG_HOME@ environment variable.
-    --   On Windows, it is @%APPDATA%@
-    --   (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).
-    --   Can be considered as the user-specific equivalent of @\/etc@.
-  | XdgCache
-    -- ^ For non-essential files (e.g. cache).
-    --   Defaults to @~\/.cache@ and can be
-    --   overridden by the @XDG_CACHE_HOME@ environment variable.
-    --   On Windows, it is @%LOCALAPPDATA%@
-    --   (e.g. @C:\/Users\//\<user\>/\/AppData\/Local@).
-    --   Can be considered as the user-specific equivalent of @\/var\/cache@.
-  deriving (Bounded, Enum, Eq, Ord, Read, Show)
-
--- | Obtain the paths to special directories for storing user-specific
---   application data, configuration, and cache files, conforming to the
---   <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
---   Compared with 'getAppUserDataDirectory', this function provides a more
---   fine-grained hierarchy as well as greater flexibility for the user.
---
---   It also works on Windows, although in that case 'XdgData' and 'XdgConfig'
---   will map to the same directory.
---
---   The second argument is usually the name of the application.  Since it
---   will be integrated into the path, it must consist of valid path
---   characters.
---
---   Note: The directory may not actually exist, in which case you would need
---   to create it with file mode @700@ (i.e. only accessible by the owner).
---
---   @since 1.2.3.0
-getXdgDirectory :: XdgDirectory         -- ^ which special directory
-                -> FilePath             -- ^ a relative path that is appended
-                                        --   to the path; if empty, the base
-                                        --   path is returned
-                -> IO FilePath
-getXdgDirectory xdgDir suffix =
-  modifyIOError (`ioeAddLocation` "getXdgDirectory") $
-  normalise . (</> suffix) <$>
-  case xdgDir of
-    XdgData   -> get False "XDG_DATA_HOME"   ".local/share"
-    XdgConfig -> get False "XDG_CONFIG_HOME" ".config"
-    XdgCache  -> get True  "XDG_CACHE_HOME"  ".cache"
-  where
-#if defined(mingw32_HOST_OS)
-    get isLocal _ _ = Win32.sHGetFolderPath nullPtr which nullPtr 0
-      where which | isLocal   = win32_cSIDL_LOCAL_APPDATA
-                  | otherwise = Win32.cSIDL_APPDATA
-#else
-    get _ name fallback = do
-      env <- lookupEnv name
-      case env of
-        Nothing                     -> fallback'
-        Just path | isRelative path -> fallback'
-                  | otherwise       -> return path
-      where fallback' = (</> fallback) <$> getHomeDirectory
-
--- | Return the value of an environment variable, or 'Nothing' if there is no
---   such value.  (Equivalent to "lookupEnv" from base-4.6.)
-lookupEnv :: String -> IO (Maybe String)
-lookupEnv name = do
-  env <- tryIOErrorType isDoesNotExistError (getEnv name)
-  case env of
-    Left  _     -> return Nothing
-    Right value -> return (Just value)
-#endif
-
--- | Similar to 'try' but only catches a specify kind of 'IOError' as
---   specified by the predicate.
-tryIOErrorType :: (IOError -> Bool) -> IO a -> IO (Either IOError a)
-tryIOErrorType check action = do
-  result <- tryIOError action
-  case result of
-    Left  err -> if check err then return (Left err) else ioError err
-    Right val -> return (Right val)
-
-specializeErrorString :: String -> (IOError -> Bool) -> IO a -> IO a
-specializeErrorString str errType action = do
-  mx <- tryIOErrorType errType action
-  case mx of
-    Left  e -> ioError (ioeSetErrorString e str)
-    Right x -> return x
-
--- | Obtain the path to a special directory for storing user-specific
---   application data (traditional Unix location).  Newer applications may
---   prefer the the XDG-conformant location provided by 'getXdgDirectory'
---   (<https://github.com/haskell/directory/issues/6#issuecomment-96521020 migration guide>).
---
---   The argument is usually the name of the application.  Since it will be
---   integrated into the path, it must consist of valid path characters.
---
---   * On Unix-like systems, the path is @~\/./\<app\>/@.
---   * On Windows, the path is @%APPDATA%\//\<app\>/@
---     (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming\//\<app\>/@)
---
---   Note: the directory may not actually exist, in which case you would need
---   to create it.  It is expected that the parent directory exists and is
---   writable.
---
---   The operation may fail with:
---
---   * 'UnsupportedOperation'
---     The operating system has no notion of application-specific data
---     directory.
---
---   * 'isDoesNotExistError'
---     The home directory for the current user does not exist, or cannot be
---     found.
---
-getAppUserDataDirectory :: FilePath     -- ^ a relative path that is appended
-                                        --   to the path
-                        -> IO FilePath
-getAppUserDataDirectory appName = do
-  modifyIOError (`ioeAddLocation` "getAppUserDataDirectory") $ do
-#if defined(mingw32_HOST_OS)
-    s <- Win32.sHGetFolderPath nullPtr Win32.cSIDL_APPDATA nullPtr 0
-    return (s++'\\':appName)
-#else
-    path <- getEnv "HOME"
-    return (path++'/':'.':appName)
-#endif
-
-{- | Returns the current user's document directory.
-
-The directory returned is expected to be writable by the current user,
-but note that it isn't generally considered good practice to store
-application-specific data here; use 'getXdgDirectory' or
-'getAppUserDataDirectory' instead.
-
-On Unix, 'getUserDocumentsDirectory' returns the value of the @HOME@
-environment variable.  On Windows, the system is queried for a
-suitable path; a typical path might be @C:\/Users\//\<user\>/\/Documents@.
-
-The operation may fail with:
-
-* 'UnsupportedOperation'
-The operating system has no notion of document directory.
-
-* 'isDoesNotExistError'
-The document directory for the current user does not exist, or
-cannot be found.
--}
-getUserDocumentsDirectory :: IO FilePath
-getUserDocumentsDirectory = do
-  modifyIOError (`ioeAddLocation` "getUserDocumentsDirectory") $ do
-#if defined(mingw32_HOST_OS)
-    Win32.sHGetFolderPath nullPtr Win32.cSIDL_PERSONAL nullPtr 0
-#else
-    getEnv "HOME"
-#endif
-
-{- | Returns the current directory for temporary files.
-
-On Unix, 'getTemporaryDirectory' returns the value of the @TMPDIR@
-environment variable or \"\/tmp\" if the variable isn\'t defined.
-On Windows, the function checks for the existence of environment variables in
-the following order and uses the first path found:
-
-*
-TMP environment variable.
-
-*
-TEMP environment variable.
-
-*
-USERPROFILE environment variable.
-
-*
-The Windows directory
-
-The operation may fail with:
-
-* 'UnsupportedOperation'
-The operating system has no notion of temporary directory.
-
-The function doesn\'t verify whether the path exists.
--}
-getTemporaryDirectory :: IO FilePath
-getTemporaryDirectory =
-#if defined(mingw32_HOST_OS)
-  Win32.getTemporaryDirectory
-#else
-  getEnv "TMPDIR" `catchIOError` \ err ->
-  if isDoesNotExistError err then return "/tmp" else ioError err
-#endif
-
-ioeAddLocation :: IOError -> String -> IOError
-ioeAddLocation e loc = do
-  ioeSetLocation e newLoc
-  where
-    newLoc = loc <> if null oldLoc then "" else ":" <> oldLoc
-    oldLoc = ioeGetLocation e
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  System.Directory
+-- Copyright   :  (c) The University of Glasgow 2001
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- System-independent interface to directory manipulation (FilePath API).
+--
+-----------------------------------------------------------------------------
+
+module System.Directory
+   (
+    -- $intro
+
+    -- * Actions on directories
+      createDirectory
+    , createDirectoryIfMissing
+    , removeDirectory
+    , removeDirectoryRecursive
+    , removePathForcibly
+    , renameDirectory
+    , listDirectory
+    , getDirectoryContents
+    -- ** Current working directory
+    , getCurrentDirectory
+    , setCurrentDirectory
+    , withCurrentDirectory
+
+    -- * Pre-defined directories
+    , getHomeDirectory
+    , XdgDirectory(..)
+    , getXdgDirectory
+    , XdgDirectoryList(..)
+    , getXdgDirectoryList
+    , getAppUserDataDirectory
+    , getUserDocumentsDirectory
+    , getTemporaryDirectory
+
+    -- * PATH
+    , getExecSearchPath
+
+    -- * Actions on files
+    , removeFile
+    , renameFile
+    , renamePath
+    , copyFile
+    , copyFileWithMetadata
+    , getFileSize
+
+    , canonicalizePath
+    , makeAbsolute
+    , makeRelativeToCurrentDirectory
+
+    -- * Existence tests
+    , doesPathExist
+    , doesFileExist
+    , doesDirectoryExist
+
+    , findExecutable
+    , findExecutables
+    , findExecutablesInDirectories
+    , findFile
+    , findFiles
+    , findFileWith
+    , findFilesWith
+    , exeExtension
+
+    -- * Symbolic links
+    , createFileLink
+    , createDirectoryLink
+    , removeDirectoryLink
+    , pathIsSymbolicLink
+    , getSymbolicLinkTarget
+
+    -- * Permissions
+
+    -- $permissions
+
+    , Permissions
+    , emptyPermissions
+    , readable
+    , writable
+    , executable
+    , searchable
+    , setOwnerReadable
+    , setOwnerWritable
+    , setOwnerExecutable
+    , setOwnerSearchable
+
+    , getPermissions
+    , setPermissions
+    , copyPermissions
+
+    -- * Timestamps
+
+    , getAccessTime
+    , getModificationTime
+    , setAccessTime
+    , setModificationTime
+
+    -- * Deprecated
+    , isSymbolicLink
+
+   ) where
+import Prelude ()
+import System.Directory.Internal
+import System.Directory.Internal.Prelude
+import Data.Time (UTCTime)
+import System.OsPath (decodeFS, encodeFS)
+import qualified System.Directory.OsPath as D
+
+{- $intro
+A directory contains a series of entries, each of which is a named
+reference to a file system object (file, directory etc.).  Some
+entries may be hidden, inaccessible, or have some administrative
+function (e.g. @.@ or @..@ under
+<http://www.opengroup.org/onlinepubs/009695399 POSIX>), but in
+this standard all such entries are considered to form part of the
+directory contents. Entries in sub-directories are not, however,
+considered to form part of the directory contents.
+
+Each file system object is referenced by a /path/.  There is
+normally at least one absolute path to each file system object.  In
+some operating systems, it may also be possible to have paths which
+are relative to the current directory.
+
+Unless otherwise documented:
+
+* 'IO' operations in this package may throw any 'IOError'.  No other types of
+  exceptions shall be thrown.
+
+* The list of possible 'IOErrorType's in the API documentation is not
+  exhaustive.  The full list may vary by platform and/or evolve over time.
+
+-}
+
+-----------------------------------------------------------------------------
+-- Permissions
+
+{- $permissions
+
+directory offers a limited (and quirky) interface for reading and setting file
+and directory permissions; see 'getPermissions' and 'setPermissions' for a
+discussion of their limitations.  Because permissions are very difficult to
+implement portably across different platforms, users who wish to do more
+sophisticated things with permissions are advised to use other,
+platform-specific libraries instead.  For example, if you are only interested
+in permissions on POSIX-like platforms,
+<https://hackage.haskell.org/package/unix/docs/System-Posix-Files.html unix>
+offers much more flexibility.
+
+ The 'Permissions' type is used to record whether certain operations are
+ permissible on a file\/directory. 'getPermissions' and 'setPermissions'
+ get and set these permissions, respectively. Permissions apply both to
+ files and directories. For directories, the executable field will be
+ 'False', and for files the searchable field will be 'False'. Note that
+ directories may be searchable without being readable, if permission has
+ been given to use them as part of a path, but not to examine the
+ directory contents.
+
+Note that to change some, but not all permissions, a construct on the
+following lines must be used.
+
+>  makeReadable f = do
+>     p <- getPermissions f
+>     setPermissions f (p {readable = True})
+
+-}
+
+emptyPermissions :: Permissions
+emptyPermissions = Permissions {
+                       readable   = False,
+                       writable   = False,
+                       executable = False,
+                       searchable = False
+                   }
+
+setOwnerReadable :: Bool -> Permissions -> Permissions
+setOwnerReadable b p = p { readable = b }
+
+setOwnerWritable :: Bool -> Permissions -> Permissions
+setOwnerWritable b p = p { writable = b }
+
+setOwnerExecutable :: Bool -> Permissions -> Permissions
+setOwnerExecutable b p = p { executable = b }
+
+setOwnerSearchable :: Bool -> Permissions -> Permissions
+setOwnerSearchable b p = p { searchable = b }
+
+-- | Get the permissions of a file or directory.
+--
+-- On Windows, the 'writable' permission corresponds to the "read-only"
+-- attribute.  The 'executable' permission is set if the file extension is of
+-- an executable file type.  The 'readable' permission is always set.
+--
+-- On POSIX systems, this returns the result of @access@.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to access the
+--   permissions, or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+getPermissions :: FilePath -> IO Permissions
+getPermissions = encodeFS >=> D.getPermissions
+
+-- | Set the permissions of a file or directory.
+--
+-- On Windows, this is only capable of changing the 'writable' permission,
+-- which corresponds to the "read-only" attribute.  Changing the other
+-- permissions has no effect.
+--
+-- On POSIX systems, this sets the /owner/ permissions.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to set the permissions,
+--   or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+setPermissions :: FilePath -> Permissions -> IO ()
+setPermissions path p = encodeFS path >>= (`D.setPermissions` p)
+
+-- | Copy the permissions of one file to another.  This reproduces the
+-- permissions more accurately than using 'getPermissions' followed by
+-- 'setPermissions'.
+--
+-- On Windows, this copies only the read-only attribute.
+--
+-- On POSIX systems, this is equivalent to @stat@ followed by @chmod@.
+copyPermissions :: FilePath -> FilePath -> IO ()
+copyPermissions src dst = do
+  src' <- encodeFS src
+  dst' <- encodeFS dst
+  D.copyPermissions src' dst'
+
+
+-----------------------------------------------------------------------------
+-- Implementation
+
+{- |@'createDirectory' dir@ creates a new directory @dir@ which is
+initially empty, or as near to empty as the operating system
+allows.
+
+The operation may fail with:
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES]@
+
+* 'isAlreadyExistsError'
+The operand refers to a directory that already exists.
+@ [EEXIST]@
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+The operand is not a valid directory name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+There is no path to the directory.
+@[ENOENT, ENOTDIR]@
+
+* 'System.IO.isFullError'
+Insufficient resources (virtual memory, process file descriptors,
+physical disk space, etc.) are available to perform the operation.
+@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+
+* @InappropriateType@
+The path refers to an existing non-directory object.
+@[EEXIST]@
+
+-}
+
+createDirectory :: FilePath -> IO ()
+createDirectory = encodeFS >=> D.createDirectory
+
+-- | @'createDirectoryIfMissing' parents dir@ creates a new directory
+-- @dir@ if it doesn\'t exist. If the first argument is 'True'
+-- the function will also create all parent directories if they are missing.
+createDirectoryIfMissing
+  :: Bool     -- ^ Create its parents too?
+  -> FilePath -- ^ The path to the directory you want to make
+  -> IO ()
+createDirectoryIfMissing cp = encodeFS >=> D.createDirectoryIfMissing cp
+
+
+{- | @'removeDirectory' dir@ removes an existing directory /dir/.  The
+implementation may specify additional constraints which must be
+satisfied before a directory can be removed (e.g. the directory has to
+be empty, or may not be in use by other processes).  It is not legal
+for an implementation to partially remove a directory unless the
+entire directory is removed. A conformant implementation need not
+support directory removal in all situations (e.g. removal of the root
+directory).
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+The operand is not a valid directory name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The directory does not exist.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY, ENOTEMPTY, EEXIST]@
+
+* @UnsupportedOperation@
+The implementation does not support removal in this situation.
+@[EINVAL]@
+
+* @InappropriateType@
+The operand refers to an existing non-directory object.
+@[ENOTDIR]@
+
+-}
+
+removeDirectory :: FilePath -> IO ()
+removeDirectory = encodeFS >=> D.removeDirectory
+
+-- | @'removeDirectoryRecursive' dir@ removes an existing directory /dir/
+-- together with its contents and subdirectories. Within this directory,
+-- symbolic links are removed without affecting their targets.
+--
+-- On Windows, the operation fails if /dir/ is a directory symbolic link.
+--
+-- This operation is reported to be flaky on Windows so retry logic may
+-- be advisable. See: https://github.com/haskell/directory/pull/108
+removeDirectoryRecursive :: FilePath -> IO ()
+removeDirectoryRecursive = encodeFS >=> D.removeDirectoryRecursive
+
+-- | Removes a file or directory at /path/ together with its contents and
+-- subdirectories. Symbolic links are removed without affecting their
+-- targets. If the path does not exist, nothing happens.
+--
+-- Unlike other removal functions, this function will also attempt to delete
+-- files marked as read-only or otherwise made unremovable due to permissions.
+-- As a result, if the removal is incomplete, the permissions or attributes on
+-- the remaining files may be altered.  If there are hard links in the
+-- directory, then permissions on all related hard links may be altered.
+--
+-- If an entry within the directory vanishes while @removePathForcibly@ is
+-- running, it is silently ignored.
+--
+-- If an exception occurs while removing an entry, @removePathForcibly@ will
+-- still try to remove as many entries as it can before failing with an
+-- exception.  The first exception that it encountered is re-thrown.
+--
+-- @since 1.2.7.0
+removePathForcibly :: FilePath -> IO ()
+removePathForcibly = encodeFS >=> D.removePathForcibly
+
+{- |'removeFile' /file/ removes the directory entry for an existing file
+/file/, where /file/ is not itself a directory. The
+implementation may specify additional constraints which must be
+satisfied before a file can be removed (e.g. the file may not be in
+use by other processes).
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+The operand is not a valid file name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The file does not exist.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY]@
+
+* @InappropriateType@
+The operand refers to an existing directory.
+@[EPERM, EINVAL]@
+
+-}
+
+removeFile :: FilePath -> IO ()
+removeFile = encodeFS >=> D.removeFile
+
+{- |@'renameDirectory' old new@ changes the name of an existing
+directory from /old/ to /new/.  If the /new/ directory
+already exists, it is atomically replaced by the /old/ directory.
+If the /new/ directory is neither the /old/ directory nor an
+alias of the /old/ directory, it is removed as if by
+'removeDirectory'.  A conformant implementation need not support
+renaming directories in all situations (e.g. renaming to an existing
+directory, or across different physical devices), but the constraints
+must be documented.
+
+On Win32 platforms, @renameDirectory@ fails if the /new/ directory already
+exists.
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+Either operand is not a valid directory name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The original directory does not exist, or there is no path to the target.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* 'System.IO.isFullError'
+Insufficient resources are available to perform the operation.
+@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY, ENOTEMPTY, EEXIST]@
+
+* @UnsupportedOperation@
+The implementation does not support renaming in this situation.
+@[EINVAL, EXDEV]@
+
+* @InappropriateType@
+Either path refers to an existing non-directory object.
+@[ENOTDIR, EISDIR]@
+
+-}
+
+renameDirectory :: FilePath -> FilePath -> IO ()
+renameDirectory opath npath = do
+  opath' <- encodeFS opath
+  npath' <- encodeFS npath
+  D.renameDirectory opath' npath'
+
+{- |@'renameFile' old new@ changes the name of an existing file system
+object from /old/ to /new/.  If the /new/ object already exists, it is
+replaced by the /old/ object.  Neither path may refer to an existing
+directory.
+
+A conformant implementation need not support renaming files in all situations
+(e.g. renaming across different physical devices), but the constraints must be
+documented. On Windows, this does not support renaming across different physical
+devices; if you are looking to do so, consider using 'copyFileWithMetadata' and
+'removeFile'.
+
+On Windows, this calls @MoveFileEx@ with @MOVEFILE_REPLACE_EXISTING@ set,
+which is not guaranteed to be atomic
+(<https://github.com/haskell/directory/issues/109>).
+
+On other platforms, this operation is atomic.
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+Either operand is not a valid file name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The original file does not exist, or there is no path to the target.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* 'System.IO.isFullError'
+Insufficient resources are available to perform the operation.
+@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY]@
+
+* @UnsupportedOperation@
+The implementation does not support renaming in this situation.
+@[EXDEV]@
+
+* @InappropriateType@
+Either path refers to an existing directory.
+@[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]@
+
+-}
+
+renameFile :: FilePath -> FilePath -> IO ()
+renameFile opath npath = do
+  opath' <- encodeFS opath
+  npath' <- encodeFS npath
+  D.renameFile opath' npath'
+
+-- | Rename a file or directory.  If the destination path already exists, it
+-- is replaced atomically.  The destination path must not point to an existing
+-- directory.  A conformant implementation need not support renaming files in
+-- all situations (e.g. renaming across different physical devices), but the
+-- constraints must be documented.
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+-- A physical I\/O error has occurred.
+-- @[EIO]@
+--
+-- * @InvalidArgument@
+-- Either operand is not a valid file name.
+-- @[ENAMETOOLONG, ELOOP]@
+--
+-- * 'isDoesNotExistError'
+-- The original file does not exist, or there is no path to the target.
+-- @[ENOENT, ENOTDIR]@
+--
+-- * 'isPermissionError'
+-- The process has insufficient privileges to perform the operation.
+-- @[EROFS, EACCES, EPERM]@
+--
+-- * 'System.IO.isFullError'
+-- Insufficient resources are available to perform the operation.
+-- @[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+--
+-- * @UnsatisfiedConstraints@
+-- Implementation-dependent constraints are not satisfied.
+-- @[EBUSY]@
+--
+-- * @UnsupportedOperation@
+-- The implementation does not support renaming in this situation.
+-- @[EXDEV]@
+--
+-- * @InappropriateType@
+-- Either the destination path refers to an existing directory, or one of the
+-- parent segments in the destination path is not a directory.
+-- @[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]@
+--
+-- @since 1.2.7.0
+renamePath :: FilePath                  -- ^ Old path
+           -> FilePath                  -- ^ New path
+           -> IO ()
+renamePath opath npath = do
+  opath' <- encodeFS opath
+  npath' <- encodeFS npath
+  D.renamePath opath' npath'
+
+-- | Copy a file with its permissions.  If the destination file already exists,
+-- it is replaced atomically.  Neither path may refer to an existing
+-- directory.  No exceptions are thrown if the permissions could not be
+-- copied.
+copyFile :: FilePath                    -- ^ Source filename
+         -> FilePath                    -- ^ Destination filename
+         -> IO ()
+copyFile fromFPath toFPath = do
+  fromFPath' <- encodeFS fromFPath
+  toFPath' <- encodeFS toFPath
+  D.copyFile fromFPath' toFPath'
+
+-- | Copy a file with its associated metadata.  If the destination file
+-- already exists, it is overwritten.  There is no guarantee of atomicity in
+-- the replacement of the destination file.  Neither path may refer to an
+-- existing directory.  If the source and/or destination are symbolic links,
+-- the copy is performed on the targets of the links.
+--
+-- On Windows, it behaves like the Win32 function
+-- <https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851.aspx CopyFile>,
+-- which copies various kinds of metadata including file attributes and
+-- security resource properties.
+--
+-- On Unix-like systems, permissions, access time, and modification time are
+-- preserved.  If possible, the owner and group are also preserved.  Note that
+-- the very act of copying can change the access time of the source file,
+-- hence the access times of the two files may differ after the operation
+-- completes.
+--
+-- @since 1.2.6.0
+copyFileWithMetadata :: FilePath        -- ^ Source file
+                     -> FilePath        -- ^ Destination file
+                     -> IO ()
+copyFileWithMetadata src dst = do
+  src' <- encodeFS src
+  dst' <- encodeFS dst
+  D.copyFileWithMetadata src' dst'
+
+
+-- | Make a path absolute, normalize the path, and remove as many indirections
+-- from it as possible.  Any trailing path separators are discarded via
+-- 'dropTrailingPathSeparator'.  Additionally, on Windows the letter case of
+-- the path is canonicalized.
+--
+-- __Note__: This function is a very big hammer.  If you only need an absolute
+-- path, 'makeAbsolute' is sufficient for removing dependence on the current
+-- working directory.
+--
+-- Indirections include the two special directories @.@ and @..@, as well as
+-- any symbolic links (and junction points on Windows).  The input path need
+-- not point to an existing file or directory.  Canonicalization is performed
+-- on the longest prefix of the path that points to an existing file or
+-- directory.  The remaining portion of the path that does not point to an
+-- existing file or directory will still be normalized, but case
+-- canonicalization and indirection removal are skipped as they are impossible
+-- to do on a nonexistent path.
+--
+-- Most programs should not worry about the canonicity of a path.  In
+-- particular, despite the name, the function does not truly guarantee
+-- canonicity of the returned path due to the presence of hard links, mount
+-- points, etc.
+--
+-- If the path points to an existing file or directory, then the output path
+-- shall also point to the same file or directory, subject to the condition
+-- that the relevant parts of the file system do not change while the function
+-- is still running.  In other words, the function is definitively not atomic.
+-- The results can be utterly wrong if the portions of the path change while
+-- this function is running.
+--
+-- Since some indirections (symbolic links on all systems, @..@ on non-Windows
+-- systems, and junction points on Windows) are dependent on the state of the
+-- existing filesystem, the function can only make a conservative attempt by
+-- removing such indirections from the longest prefix of the path that still
+-- points to an existing file or directory.
+--
+-- Note that on Windows parent directories @..@ are always fully expanded
+-- before the symbolic links, as consistent with the rest of the Windows API
+-- (such as @GetFullPathName@).  In contrast, on POSIX systems parent
+-- directories @..@ are expanded alongside symbolic links from left to right.
+-- To put this more concretely: if @L@ is a symbolic link for @R/P@, then on
+-- Windows @L\\..@ refers to @.@, whereas on other operating systems @L/..@
+-- refers to @R@.
+--
+-- Similar to 'System.FilePath.normalise', passing an empty path is equivalent
+-- to passing the current directory.
+--
+-- @canonicalizePath@ can resolve at least 64 indirections in a single path,
+-- more than what is supported by most operating systems.  Therefore, it may
+-- return the fully resolved path even though the operating system itself
+-- would have long given up.
+--
+-- On Windows XP or earlier systems, junction expansion is not performed due
+-- to their lack of @GetFinalPathNameByHandle@.
+--
+-- /Changes since 1.2.3.0:/ The function has been altered to be more robust
+-- and has the same exception behavior as 'makeAbsolute'.
+--
+-- /Changes since 1.3.0.0:/ The function no longer preserves the trailing path
+-- separator.  File symbolic links that appear in the middle of a path are
+-- properly dereferenced.  Case canonicalization and symbolic link expansion
+-- are now performed on Windows.
+--
+canonicalizePath :: FilePath -> IO FilePath
+canonicalizePath = encodeFS >=> D.canonicalizePath >=> decodeFS
+
+-- | Convert a path into an absolute path.  If the given path is relative, the
+-- current directory is prepended and then the combined result is normalized.
+-- If the path is already absolute, the path is simply normalized.  The
+-- function preserves the presence or absence of the trailing path separator
+-- unless the path refers to the root directory @/@.
+--
+-- If the path is already absolute, the operation never fails.  Otherwise, the
+-- operation may fail with the same exceptions as 'getCurrentDirectory'.
+--
+-- @since 1.2.2.0
+--
+makeAbsolute :: FilePath -> IO FilePath
+makeAbsolute = encodeFS >=> D.makeAbsolute >=> decodeFS
+
+-- | Construct a path relative to the current directory, similar to
+-- 'makeRelative'.
+--
+-- The operation may fail with the same exceptions as 'getCurrentDirectory'.
+makeRelativeToCurrentDirectory :: FilePath -> IO FilePath
+makeRelativeToCurrentDirectory =
+  encodeFS >=> D.makeRelativeToCurrentDirectory >=> decodeFS
+
+-- | Given the name or path of an executable file, 'findExecutable' searches
+-- for such a file in a list of system-defined locations, which generally
+-- includes @PATH@ and possibly more.  The full path to the executable is
+-- returned if found.  For example, @(findExecutable \"ghc\")@ would normally
+-- give you the path to GHC.
+--
+-- The path returned by @'findExecutable' name@ corresponds to the program
+-- that would be executed by
+-- @<http://hackage.haskell.org/package/process/docs/System-Process.html#v:createProcess createProcess>@
+-- when passed the same string (as a @RawCommand@, not a @ShellCommand@),
+-- provided that @name@ is not a relative path with more than one segment.
+--
+-- On Windows, 'findExecutable' calls the Win32 function
+-- @<https://msdn.microsoft.com/en-us/library/aa365527.aspx SearchPath>@,
+-- which may search other places before checking the directories in the @PATH@
+-- environment variable.  Where it actually searches depends on registry
+-- settings, but notably includes the directory containing the current
+-- executable.
+--
+-- On non-Windows platforms, the behavior is equivalent to 'findFileWith'
+-- using the search directories from the @PATH@ environment variable and
+-- testing each file for executable permissions.  Details can be found in the
+-- documentation of 'findFileWith'.
+findExecutable :: String -> IO (Maybe FilePath)
+findExecutable = encodeFS >=> D.findExecutable >=> (`for` decodeFS)
+
+-- | Search for executable files in a list of system-defined locations, which
+-- generally includes @PATH@ and possibly more.
+--
+-- On Windows, this /only returns the first occurrence/, if any.  Its behavior
+-- is therefore equivalent to 'findExecutable'.
+--
+-- On non-Windows platforms, the behavior is equivalent to
+-- 'findExecutablesInDirectories' using the search directories from the @PATH@
+-- environment variable.  Details can be found in the documentation of
+-- 'findExecutablesInDirectories'.
+--
+-- @since 1.2.2.0
+findExecutables :: String -> IO [FilePath]
+findExecutables = encodeFS >=> D.findExecutables >=> (`for` decodeFS)
+
+-- | Given a name or path, 'findExecutable' appends the 'exeExtension' to the
+-- query and searches for executable files in the list of given search
+-- directories and returns all occurrences.
+--
+-- The behavior is equivalent to 'findFileWith' using the given search
+-- directories and testing each file for executable permissions.  Details can
+-- be found in the documentation of 'findFileWith'.
+--
+-- Unlike other similarly named functions, 'findExecutablesInDirectories' does
+-- not use @SearchPath@ from the Win32 API.  The behavior of this function on
+-- Windows is therefore equivalent to those on non-Windows platforms.
+--
+-- @since 1.2.4.0
+findExecutablesInDirectories :: [FilePath] -> String -> IO [FilePath]
+findExecutablesInDirectories path binary = do
+  path' <- for path encodeFS
+  binary' <- encodeFS binary
+  D.findExecutablesInDirectories path' binary'
+    >>= (`for` decodeFS)
+
+-- | Search through the given list of directories for the given file.
+--
+-- The behavior is equivalent to 'findFileWith', returning only the first
+-- occurrence.  Details can be found in the documentation of 'findFileWith'.
+findFile :: [FilePath] -> String -> IO (Maybe FilePath)
+findFile = findFileWith (\ _ -> pure True)
+
+-- | Search through the given list of directories for the given file and
+-- returns all paths where the given file exists.
+--
+-- The behavior is equivalent to 'findFilesWith'.  Details can be found in the
+-- documentation of 'findFilesWith'.
+--
+-- @since 1.2.1.0
+findFiles :: [FilePath] -> String -> IO [FilePath]
+findFiles = findFilesWith (\ _ -> pure True)
+
+-- | Search through a given list of directories for a file that has the given
+-- name and satisfies the given predicate and return the path of the first
+-- occurrence.  The directories are checked in a left-to-right order.
+--
+-- This is essentially a more performant version of 'findFilesWith' that
+-- always returns the first result, if any.  Details can be found in the
+-- documentation of 'findFilesWith'.
+--
+-- @since 1.2.6.0
+findFileWith
+  :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO (Maybe FilePath)
+findFileWith f ds name = do
+  ds' <- for ds encodeFS
+  name' <- encodeFS name
+  D.findFileWith (decodeFS >=> f) ds' name'
+    >>= (`for` decodeFS)
+
+-- | @findFilesWith predicate dirs name@ searches through the list of
+-- directories (@dirs@) for files that have the given @name@ and satisfy the
+-- given @predicate@ and returns the paths of those files.  The directories
+-- are checked in a left-to-right order and the paths are returned in the same
+-- order.
+--
+-- If the @name@ is a relative path, then for every search directory @dir@,
+-- the function checks whether @dir '</>' name@ exists and satisfies the
+-- predicate.  If so, @dir '</>' name@ is returned as one of the results.  In
+-- other words, the returned paths can be either relative or absolute
+-- depending on the search directories were used.  If there are no search
+-- directories, no results are ever returned.
+--
+-- If the @name@ is an absolute path, then the function will return a single
+-- result if the file exists and satisfies the predicate and no results
+-- otherwise.  This is irrespective of what search directories were given.
+--
+-- @since 1.2.1.0
+findFilesWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO [FilePath]
+findFilesWith f ds name = do
+  ds' <- for ds encodeFS
+  name' <- encodeFS name
+  res <- D.findFilesWith (decodeFS >=> f) ds' name'
+  for res decodeFS
+
+-- | Filename extension for executable files (including the dot if any)
+--   (usually @\"\"@ on POSIX systems and @\".exe\"@ on Windows or OS\/2).
+--
+-- @since 1.2.4.0
+exeExtension :: String
+exeExtension = so D.exeExtension
+
+-- | Similar to 'listDirectory', but always includes the special entries (@.@
+-- and @..@).  (This applies to Windows as well.)
+--
+-- The operation may fail with the same exceptions as 'listDirectory'.
+getDirectoryContents :: FilePath -> IO [FilePath]
+getDirectoryContents = encodeFS >=> D.getDirectoryContents >=> (`for` decodeFS)
+
+-- | @'listDirectory' dir@ returns a list of /all/ entries in /dir/ without
+-- the special entries (@.@ and @..@).
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+--   A physical I\/O error has occurred.
+--   @[EIO]@
+--
+-- * @InvalidArgument@
+--   The operand is not a valid directory name.
+--   @[ENAMETOOLONG, ELOOP]@
+--
+-- * 'isDoesNotExistError'
+--   The directory does not exist.
+--   @[ENOENT, ENOTDIR]@
+--
+-- * 'isPermissionError'
+--   The process has insufficient privileges to perform the operation.
+--   @[EACCES]@
+--
+-- * 'System.IO.isFullError'
+--   Insufficient resources are available to perform the operation.
+--   @[EMFILE, ENFILE]@
+--
+-- * @InappropriateType@
+--   The path refers to an existing non-directory object.
+--   @[ENOTDIR]@
+--
+-- @since 1.2.5.0
+--
+listDirectory :: FilePath -> IO [FilePath]
+listDirectory = encodeFS >=> D.listDirectory >=> (`for` decodeFS)
+
+-- | Obtain the current working directory as an absolute path.
+--
+-- In a multithreaded program, the current working directory is a global state
+-- shared among all threads of the process.  Therefore, when performing
+-- filesystem operations from multiple threads, it is highly recommended to
+-- use absolute rather than relative paths (see: 'makeAbsolute').
+--
+-- Note that 'getCurrentDirectory' is not guaranteed to return the same path
+-- received by 'setCurrentDirectory'. On POSIX systems, the path returned will
+-- always be fully dereferenced (not contain any symbolic links). For more
+-- information, refer to the documentation of
+-- <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html getcwd>.
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+-- A physical I\/O error has occurred.
+-- @[EIO]@
+--
+-- * 'isDoesNotExistError'
+-- There is no path referring to the working directory.
+-- @[EPERM, ENOENT, ESTALE...]@
+--
+-- * 'isPermissionError'
+-- The process has insufficient privileges to perform the operation.
+-- @[EACCES]@
+--
+-- * 'System.IO.isFullError'
+-- Insufficient resources are available to perform the operation.
+--
+-- * @UnsupportedOperation@
+-- The operating system has no notion of current working directory.
+--
+getCurrentDirectory :: IO FilePath
+getCurrentDirectory = D.getCurrentDirectory >>= decodeFS
+
+-- | Change the working directory to the given path.
+--
+-- In a multithreaded program, the current working directory is a global state
+-- shared among all threads of the process.  Therefore, when performing
+-- filesystem operations from multiple threads, it is highly recommended to
+-- use absolute rather than relative paths (see: 'makeAbsolute').
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+-- A physical I\/O error has occurred.
+-- @[EIO]@
+--
+-- * @InvalidArgument@
+-- The operand is not a valid directory name.
+-- @[ENAMETOOLONG, ELOOP]@
+--
+-- * 'isDoesNotExistError'
+-- The directory does not exist.
+-- @[ENOENT, ENOTDIR]@
+--
+-- * 'isPermissionError'
+-- The process has insufficient privileges to perform the operation.
+-- @[EACCES]@
+--
+-- * @UnsupportedOperation@
+-- The operating system has no notion of current working directory, or the
+-- working directory cannot be dynamically changed.
+--
+-- * @InappropriateType@
+-- The path refers to an existing non-directory object.
+-- @[ENOTDIR]@
+--
+setCurrentDirectory :: FilePath -> IO ()
+setCurrentDirectory = encodeFS >=> D.setCurrentDirectory
+
+-- | Run an 'IO' action with the given working directory and restore the
+-- original working directory afterwards, even if the given action fails due
+-- to an exception.
+--
+-- The operation may fail with the same exceptions as 'getCurrentDirectory'
+-- and 'setCurrentDirectory'.
+--
+-- @since 1.2.3.0
+--
+withCurrentDirectory :: FilePath  -- ^ Directory to execute in
+                     -> IO a      -- ^ Action to be executed
+                     -> IO a
+withCurrentDirectory dir action =
+  encodeFS dir >>= (`D.withCurrentDirectory` action)
+
+-- | Obtain the size of a file in bytes.
+--
+-- @since 1.2.7.0
+getFileSize :: FilePath -> IO Integer
+getFileSize = encodeFS >=> D.getFileSize
+
+-- | Test whether the given path points to an existing filesystem object.  If
+-- the user lacks necessary permissions to search the parent directories, this
+-- function may return false even if the file does actually exist.
+--
+-- @since 1.2.7.0
+doesPathExist :: FilePath -> IO Bool
+doesPathExist = encodeFS >=> D.doesPathExist
+
+{- |The operation 'doesDirectoryExist' returns 'True' if the argument file
+exists and is either a directory or a symbolic link to a directory,
+and 'False' otherwise.
+-}
+
+doesDirectoryExist :: FilePath -> IO Bool
+doesDirectoryExist = encodeFS >=> D.doesDirectoryExist
+
+{- |The operation 'doesFileExist' returns 'True'
+if the argument file exists and is not a directory, and 'False' otherwise.
+-}
+
+doesFileExist :: FilePath -> IO Bool
+doesFileExist = encodeFS >=> D.doesFileExist
+
+
+-- | Create a /file/ symbolic link.  The target path can be either absolute or
+-- relative and need not refer to an existing file.  The order of arguments
+-- follows the POSIX convention.
+--
+-- To remove an existing file symbolic link, use 'removeFile'.
+--
+-- Although the distinction between /file/ symbolic links and /directory/
+-- symbolic links does not exist on POSIX systems, on Windows this is an
+-- intrinsic property of every symbolic link and cannot be changed without
+-- recreating the link.  A file symbolic link that actually points to a
+-- directory will fail to dereference and vice versa.  Moreover, creating
+-- symbolic links on Windows may require privileges unavailable to users
+-- outside the Administrators group.  Portable programs that use symbolic
+-- links should take both into consideration.
+--
+-- On Windows, the function is implemented using @CreateSymbolicLink@.  Since
+-- 1.3.3.0, the @SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE@ flag is included
+-- if supported by the operating system.  On POSIX, the function uses @symlink@
+-- and is therefore atomic.
+--
+-- Windows-specific errors: This operation may fail with 'permissionErrorType'
+-- if the user lacks the privileges to create symbolic links.  It may also
+-- fail with 'illegalOperationErrorType' if the file system does not support
+-- symbolic links.
+--
+-- @since 1.3.1.0
+createFileLink
+  :: FilePath                           -- ^ path to the target file
+  -> FilePath                           -- ^ path of the link to be created
+  -> IO ()
+createFileLink target link = do
+  target' <- encodeFS target
+  link' <- encodeFS link
+  D.createFileLink target' link'
+
+
+-- | Create a /directory/ symbolic link.  The target path can be either
+-- absolute or relative and need not refer to an existing directory.  The
+-- order of arguments follows the POSIX convention.
+--
+-- To remove an existing directory symbolic link, use 'removeDirectoryLink'.
+--
+-- Although the distinction between /file/ symbolic links and /directory/
+-- symbolic links does not exist on POSIX systems, on Windows this is an
+-- intrinsic property of every symbolic link and cannot be changed without
+-- recreating the link.  A file symbolic link that actually points to a
+-- directory will fail to dereference and vice versa.  Moreover, creating
+-- symbolic links on Windows may require privileges unavailable to users
+-- outside the Administrators group.  Portable programs that use symbolic
+-- links should take both into consideration.
+--
+-- On Windows, the function is implemented using @CreateSymbolicLink@ with
+-- @SYMBOLIC_LINK_FLAG_DIRECTORY@.  Since 1.3.3.0, the
+-- @SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE@ flag is also included if
+-- supported by the operating system.   On POSIX, this is an alias for
+-- 'createFileLink' and is therefore atomic.
+--
+-- Windows-specific errors: This operation may fail with 'permissionErrorType'
+-- if the user lacks the privileges to create symbolic links.  It may also
+-- fail with 'illegalOperationErrorType' if the file system does not support
+-- symbolic links.
+--
+-- @since 1.3.1.0
+createDirectoryLink
+  :: FilePath                           -- ^ path to the target directory
+  -> FilePath                           -- ^ path of the link to be created
+  -> IO ()
+createDirectoryLink target link = do
+  target' <- encodeFS target
+  link' <- encodeFS link
+  D.createDirectoryLink target' link'
+
+-- | Remove an existing /directory/ symbolic link.
+--
+-- On Windows, this is an alias for 'removeDirectory'.  On POSIX systems, this
+-- is an alias for 'removeFile'.
+--
+-- See also: 'removeFile', which can remove an existing /file/ symbolic link.
+--
+-- @since 1.3.1.0
+removeDirectoryLink :: FilePath -> IO ()
+removeDirectoryLink = encodeFS >=> D.removeDirectoryLink
+
+-- | Check whether an existing @path@ is a symbolic link.  If @path@ is a
+-- regular file or directory, 'False' is returned.  If @path@ does not exist
+-- or is otherwise inaccessible, an exception is thrown (see below).
+--
+-- On Windows, this checks for @FILE_ATTRIBUTE_REPARSE_POINT@.  In addition to
+-- symbolic links, the function also returns true on junction points.  On
+-- POSIX systems, this checks for @S_IFLNK@.
+--
+-- The operation may fail with:
+--
+-- * 'isDoesNotExistError' if the symbolic link does not exist; or
+--
+-- * 'isPermissionError' if the user is not permitted to read the symbolic
+--   link.
+--
+-- @since 1.3.0.0
+pathIsSymbolicLink :: FilePath -> IO Bool
+pathIsSymbolicLink = encodeFS >=> D.pathIsSymbolicLink
+
+{-# DEPRECATED isSymbolicLink "Use 'pathIsSymbolicLink' instead" #-}
+isSymbolicLink :: FilePath -> IO Bool
+isSymbolicLink = pathIsSymbolicLink
+
+-- | Retrieve the target path of either a file or directory symbolic link.
+-- The returned path may not be absolute, may not exist, and may not even be a
+-- valid path.
+--
+-- On Windows systems, this calls @DeviceIoControl@ with
+-- @FSCTL_GET_REPARSE_POINT@.  In addition to symbolic links, the function
+-- also works on junction points.  On POSIX systems, this calls @readlink@.
+--
+-- Windows-specific errors: This operation may fail with
+-- 'illegalOperationErrorType' if the file system does not support symbolic
+-- links.
+--
+-- @since 1.3.1.0
+getSymbolicLinkTarget :: FilePath -> IO FilePath
+getSymbolicLinkTarget = encodeFS >=> D.getSymbolicLinkTarget >=> decodeFS
+
+-- | Obtain the time at which the file or directory was last accessed.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to read
+--   the access time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- Caveat for POSIX systems: This function returns a timestamp with sub-second
+-- resolution only if this package is compiled against @unix-2.6.0.0@ or later
+-- and the underlying filesystem supports them.
+--
+-- @since 1.2.3.0
+--
+getAccessTime :: FilePath -> IO UTCTime
+getAccessTime = encodeFS >=> D.getAccessTime
+
+-- | Obtain the time at which the file or directory was last modified.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to read
+--   the modification time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- Caveat for POSIX systems: This function returns a timestamp with sub-second
+-- resolution only if this package is compiled against @unix-2.6.0.0@ or later
+-- and the underlying filesystem supports them.
+--
+getModificationTime :: FilePath -> IO UTCTime
+getModificationTime = encodeFS >=> D.getModificationTime
+
+-- | Change the time at which the file or directory was last accessed.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to alter the
+--   access time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- Some caveats for POSIX systems:
+--
+-- * Not all systems support @utimensat@, in which case the function can only
+--   emulate the behavior by reading the modification time and then setting
+--   both the access and modification times together.  On systems where
+--   @utimensat@ is supported, the access time is set atomically with
+--   nanosecond precision.
+--
+-- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function
+--   would not be able to set timestamps with sub-second resolution.  In this
+--   case, there would also be loss of precision in the modification time.
+--
+-- @since 1.2.3.0
+--
+setAccessTime :: FilePath -> UTCTime -> IO ()
+setAccessTime path atime = encodeFS path >>= (`D.setAccessTime` atime)
+
+-- | Change the time at which the file or directory was last modified.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to alter the
+--   modification time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- * 'InvalidArgument' on FAT32 file system if the time is before
+--   DOS Epoch (1 January 1980).
+--
+-- Some caveats for POSIX systems:
+--
+-- * Not all systems support @utimensat@, in which case the function can only
+--   emulate the behavior by reading the access time and then setting both the
+--   access and modification times together.  On systems where @utimensat@ is
+--   supported, the modification time is set atomically with nanosecond
+--   precision.
+--
+-- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function
+--   would not be able to set timestamps with sub-second resolution.  In this
+--   case, there would also be loss of precision in the access time.
+--
+-- @since 1.2.3.0
+--
+setModificationTime :: FilePath -> UTCTime -> IO ()
+setModificationTime path mtime =
+  encodeFS path >>= (`D.setModificationTime` mtime)
+
+{- | Returns the current user's home directory.
+
+The directory returned is expected to be writable by the current user,
+but note that it isn't generally considered good practice to store
+application-specific data here; use 'getXdgDirectory' or
+'getAppUserDataDirectory' instead.
+
+On Unix, 'getHomeDirectory' behaves as follows:
+
+* Returns $HOME env variable if set (including to an empty string).
+* Otherwise uses home directory returned by @getpwuid_r@ using the UID of the
+  current process' user. This basically reads the @\/etc\/passwd@ file. An
+  empty home directory field is considered valid.
+
+On Windows, the system is queried for a suitable path; a typical path might be
+@C:\/Users\//\<user\>/@.
+
+The operation may fail with:
+
+* @UnsupportedOperation@
+The operating system has no notion of home directory.
+
+* 'isDoesNotExistError'
+The home directory for the current user does not exist, or
+cannot be found.
+-}
+getHomeDirectory :: IO FilePath
+getHomeDirectory = D.getHomeDirectory >>= decodeFS
+
+-- | Obtain the paths to special directories for storing user-specific
+--   application data, configuration, and cache files, conforming to the
+--   <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
+--   Compared with 'getAppUserDataDirectory', this function provides a more
+--   fine-grained hierarchy as well as greater flexibility for the user.
+--
+--   On Windows, 'XdgData' and 'XdgConfig' usually map to the same directory
+--   unless overridden.
+--
+--   Refer to the docs of 'XdgDirectory' for more details.
+--
+--   The second argument is usually the name of the application.  Since it
+--   will be integrated into the path, it must consist of valid path
+--   characters.  Note: if the second argument is an absolute path, it will
+--   just return the second argument.
+--
+--   Note: The directory may not actually exist, in which case you would need
+--   to create it with file mode @700@ (i.e. only accessible by the owner).
+--
+--   As of 1.3.5.0, the environment variable is ignored if set to a relative
+--   path, per revised XDG Base Directory Specification.  See
+--   <https://github.com/haskell/directory/issues/100 #100>.
+--
+--   @since 1.2.3.0
+getXdgDirectory :: XdgDirectory         -- ^ which special directory
+                -> FilePath             -- ^ a relative path that is appended
+                                        --   to the path; if empty, the base
+                                        --   path is returned
+                -> IO FilePath
+getXdgDirectory xdgDir = encodeFS >=> D.getXdgDirectory xdgDir >=> decodeFS
+
+-- | Similar to 'getXdgDirectory' but retrieves the entire list of XDG
+-- directories.
+--
+-- On Windows, 'XdgDataDirs' and 'XdgConfigDirs' usually map to the same list
+-- of directories unless overridden.
+--
+-- Refer to the docs of 'XdgDirectoryList' for more details.
+getXdgDirectoryList :: XdgDirectoryList -- ^ which special directory list
+                    -> IO [FilePath]
+getXdgDirectoryList = D.getXdgDirectoryList >=> (`for` decodeFS)
+
+-- | Obtain the path to a special directory for storing user-specific
+--   application data (traditional Unix location).  Newer applications may
+--   prefer the the XDG-conformant location provided by 'getXdgDirectory'
+--   (<https://github.com/haskell/directory/issues/6#issuecomment-96521020 migration guide>).
+--
+--   The argument is usually the name of the application.  Since it will be
+--   integrated into the path, it must consist of valid path characters.
+--
+--   * On Unix-like systems, the path is @~\/./\<app\>/@.
+--   * On Windows, the path is @%APPDATA%\//\<app\>/@
+--     (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming\//\<app\>/@)
+--
+--   Note: the directory may not actually exist, in which case you would need
+--   to create it.  It is expected that the parent directory exists and is
+--   writable.
+--
+--   The operation may fail with:
+--
+--   * @UnsupportedOperation@
+--     The operating system has no notion of application-specific data
+--     directory.
+--
+--   * 'isDoesNotExistError'
+--     The home directory for the current user does not exist, or cannot be
+--     found.
+--
+getAppUserDataDirectory :: FilePath     -- ^ a relative path that is appended
+                                        --   to the path
+                        -> IO FilePath
+getAppUserDataDirectory = encodeFS >=> D.getAppUserDataDirectory >=>decodeFS
+
+{- | Returns the current user's document directory.
+
+The directory returned is expected to be writable by the current user,
+but note that it isn't generally considered good practice to store
+application-specific data here; use 'getXdgDirectory' or
+'getAppUserDataDirectory' instead.
+
+On Unix, 'getUserDocumentsDirectory' returns the value of the @HOME@
+environment variable.  On Windows, the system is queried for a
+suitable path; a typical path might be @C:\/Users\//\<user\>/\/Documents@.
+
+The operation may fail with:
+
+* @UnsupportedOperation@
+The operating system has no notion of document directory.
+
+* 'isDoesNotExistError'
+The document directory for the current user does not exist, or
+cannot be found.
+-}
+getUserDocumentsDirectory :: IO FilePath
+getUserDocumentsDirectory = D.getUserDocumentsDirectory >>= decodeFS
+
+{- | Returns the current directory for temporary files.
+
+On Unix, 'getTemporaryDirectory' returns the value of the @TMPDIR@
+environment variable or \"\/tmp\" if the variable isn\'t defined.
+On Windows, the function checks for the existence of environment variables in
+the following order and uses the first path found:
+
+*
+TMP environment variable.
+
+*
+TEMP environment variable.
+
+*
+USERPROFILE environment variable.
+
+*
+The Windows directory
+
+The operation may fail with:
+
+* @UnsupportedOperation@
+The operating system has no notion of temporary directory.
+
+The function doesn\'t verify whether the path exists.
+-}
+getTemporaryDirectory :: IO FilePath
+getTemporaryDirectory = D.getTemporaryDirectory >>= decodeFS
+
+-- | Get the contents of the @PATH@ environment variable.
+getExecSearchPath :: IO [FilePath]
+getExecSearchPath = D.getExecSearchPath >>= (`for` decodeFS)
diff --git a/System/Directory/Internal.hs b/System/Directory/Internal.hs
--- a/System/Directory/Internal.hs
+++ b/System/Directory/Internal.hs
@@ -1,28 +1,30 @@
 {-# LANGUAGE CPP #-}
-{-# OPTIONS_HADDOCK hide #-}
+{-# OPTIONS_HADDOCK not-home #-}
+-- |
+-- Stability: unstable
+-- Portability: unportable
+--
+-- Internal modules are always subject to change from version to version.
+-- The contents of this module are also platform-dependent, hence what is
+-- shown in the Hackage documentation may differ from what is actually
+-- available on your system.
+
 #include <HsDirectoryConfig.h>
 
 module System.Directory.Internal
-  ( module System.Directory.Internal.Config
-
-#ifdef HAVE_UTIMENSAT
-  , module System.Directory.Internal.C_utimensat
-#endif
+  ( module System.Directory.Internal.Common
 
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS)
   , module System.Directory.Internal.Windows
 #else
   , module System.Directory.Internal.Posix
 #endif
 
   ) where
-import System.Directory.Internal.Config
 
-#ifdef HAVE_UTIMENSAT
-import System.Directory.Internal.C_utimensat
-#endif
+import System.Directory.Internal.Common
 
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS)
 import System.Directory.Internal.Windows
 #else
 import System.Directory.Internal.Posix
diff --git a/System/Directory/Internal/C_utimensat.hsc b/System/Directory/Internal/C_utimensat.hsc
--- a/System/Directory/Internal/C_utimensat.hsc
+++ b/System/Directory/Internal/C_utimensat.hsc
@@ -1,3 +1,5 @@
+{-# LANGUAGE CApiFFI #-}
+
 module System.Directory.Internal.C_utimensat where
 #include <HsDirectoryConfig.h>
 #ifdef HAVE_UTIMENSAT
@@ -10,17 +12,16 @@
 #ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif
-#include <System/Directory/Internal/utility.h>
 import Prelude ()
 import System.Directory.Internal.Prelude
 import Data.Time.Clock.POSIX (POSIXTime)
+import qualified System.Posix as Posix
 
 data CTimeSpec = CTimeSpec EpochTime CLong
 
 instance Storable CTimeSpec where
     sizeOf    _ = #{size struct timespec}
-    -- workaround (hsc2hs for GHC < 8.0 doesn't support #{alignment ...})
-    alignment _ = #{size char[alignof(struct timespec)] }
+    alignment _ = #{alignment struct timespec}
     poke p (CTimeSpec sec nsec) = do
       (#poke struct timespec, tv_sec)  p sec
       (#poke struct timespec, tv_nsec) p nsec
@@ -29,9 +30,6 @@
       nsec <- #{peek struct timespec, tv_nsec} p
       return (CTimeSpec sec nsec)
 
-c_AT_FDCWD :: CInt
-c_AT_FDCWD = (#const AT_FDCWD)
-
 utimeOmit :: CTimeSpec
 utimeOmit = CTimeSpec (CTime 0) (#const UTIME_OMIT)
 
@@ -41,7 +39,7 @@
     (sec,  frac)  = if frac' < 0 then (sec' - 1, frac' + 1) else (sec', frac')
     (sec', frac') = properFraction (toRational t)
 
-foreign import ccall "utimensat" c_utimensat
-  :: CInt -> CString -> Ptr CTimeSpec -> CInt -> IO CInt
+foreign import capi "sys/stat.h utimensat" c_utimensat
+  :: Posix.Fd -> CString -> Ptr CTimeSpec -> CInt -> IO CInt
 
 #endif
diff --git a/System/Directory/Internal/Common.hs b/System/Directory/Internal/Common.hs
new file mode 100644
--- /dev/null
+++ b/System/Directory/Internal/Common.hs
@@ -0,0 +1,353 @@
+{-# LANGUAGE CPP #-}
+module System.Directory.Internal.Common
+  ( module System.Directory.Internal.Common
+  , OsPath
+  , OsString
+  ) where
+import Prelude ()
+import System.Directory.Internal.Prelude
+import GHC.IO.Encoding.Failure (CodingFailureMode(TransliterateCodingFailure))
+import GHC.IO.Encoding.UTF16 (mkUTF16le)
+import GHC.IO.Encoding.UTF8 (mkUTF8)
+import qualified System.File.OsPath.Internal as File
+import System.OsPath
+  ( OsPath
+  , OsString
+  , addTrailingPathSeparator
+  , decodeUtf
+  , decodeWith
+  , encodeUtf
+  , hasTrailingPathSeparator
+  , isPathSeparator
+  , isRelative
+  , joinDrive
+  , joinPath
+  , normalise
+  , pack
+  , pathSeparator
+  , pathSeparators
+  , splitDirectories
+  , splitDrive
+  , toChar
+  , unpack
+  , unsafeFromChar
+  )
+
+-- | A generator with side-effects.
+newtype ListT m a = ListT { unListT :: m (Maybe (a, ListT m a)) }
+
+emptyListT :: Applicative m => ListT m a
+emptyListT = ListT (pure Nothing)
+
+maybeToListT :: Applicative m => m (Maybe a) -> ListT m a
+maybeToListT m = ListT (((\ x -> (x, emptyListT)) <$>) <$> m)
+
+listToListT :: Applicative m => [a] -> ListT m a
+listToListT [] = emptyListT
+listToListT (x : xs) = ListT (pure (Just (x, listToListT xs)))
+
+liftJoinListT :: Monad m => m (ListT m a) -> ListT m a
+liftJoinListT m = ListT (m >>= unListT)
+
+listTHead :: Functor m => ListT m a -> m (Maybe a)
+listTHead (ListT m) = (fst <$>) <$> m
+
+listTToList :: Monad m => ListT m a -> m [a]
+listTToList (ListT m) = do
+  mx <- m
+  case mx of
+    Nothing -> pure []
+    Just (x, m') -> do
+      xs <- listTToList m'
+      pure (x : xs)
+
+andM :: Monad m => m Bool -> m Bool -> m Bool
+andM mx my = do
+  x <- mx
+  if x
+    then my
+    else pure x
+
+sequenceWithIOErrors_ :: [IO ()] -> IO ()
+sequenceWithIOErrors_ actions = go (Right ()) actions
+  where
+
+    go :: Either IOError () -> [IO ()] -> IO ()
+    go (Left e)   []       = ioError e
+    go (Right ()) []       = pure ()
+    go s          (m : ms) = s `seq` do
+      r <- tryIOError m
+      go (s *> r) ms
+
+-- | Similar to 'try' but only catches a specify kind of 'IOError' as
+--   specified by the predicate.
+tryIOErrorType :: (IOError -> Bool) -> IO a -> IO (Either IOError a)
+tryIOErrorType check action = do
+  result <- tryIOError action
+  case result of
+    Left  err -> if check err then pure (Left err) else throwIO err
+    Right val -> pure (Right val)
+
+-- | Attempt to perform the given action, silencing any IO exception thrown by
+-- it.
+ignoreIOExceptions :: IO () -> IO ()
+ignoreIOExceptions io = io `catchIOError` (\_ -> pure ())
+
+specializeErrorString :: String -> (IOError -> Bool) -> IO a -> IO a
+specializeErrorString str errType action = do
+  mx <- tryIOErrorType errType action
+  case mx of
+    Left  e -> throwIO (ioeSetErrorString e str)
+    Right x -> pure x
+
+ioeAddLocation :: IOError -> String -> IOError
+ioeAddLocation e loc = do
+  ioeSetLocation e newLoc
+  where
+    newLoc = loc <> if null oldLoc then "" else ":" <> oldLoc
+    oldLoc = ioeGetLocation e
+
+rightOrError :: Exception e => Either e a -> a
+rightOrError (Left e)  = error (displayException e)
+rightOrError (Right a) = a
+
+-- | Fallibly converts String to OsString. Only intended to be used on literals.
+os :: String -> OsString
+os = rightOrError . encodeUtf
+
+-- | Fallibly converts OsString to String. Only intended to be used on literals.
+so :: OsString -> String
+so = rightOrError . decodeUtf
+
+ioeSetOsPath :: IOError -> OsPath -> IOError
+ioeSetOsPath err =
+  ioeSetFileName err .
+  rightOrError .
+  decodeWith
+    (mkUTF8 TransliterateCodingFailure)
+    (mkUTF16le TransliterateCodingFailure)
+
+dropSpecialDotDirs :: [OsPath] -> [OsPath]
+dropSpecialDotDirs = filter f
+  where f filename = filename /= os "." && filename /= os ".."
+
+-- | Given a list of path segments, expand @.@ and @..@.  The path segments
+-- must not contain path separators.
+expandDots :: [OsPath] -> [OsPath]
+expandDots = reverse . go []
+  where
+    go ys' xs' =
+      case xs' of
+        [] -> ys'
+        x : xs
+          | x == os "." -> go ys' xs
+          | x == os ".." ->
+              case ys' of
+                [] -> go (x : ys') xs
+                y : ys
+                  | y == os ".." -> go (x : ys') xs
+                  | otherwise -> go ys xs
+          | otherwise -> go (x : ys') xs
+
+-- | Convert to the right kind of slashes.
+normalisePathSeps :: OsPath -> OsPath
+normalisePathSeps p = pack (normaliseChar <$> unpack p)
+  where normaliseChar c = if isPathSeparator c then pathSeparator else c
+
+-- | Remove redundant trailing slashes and pick the right kind of slash.
+normaliseTrailingSep :: OsPath -> OsPath
+normaliseTrailingSep path = do
+  let path' = reverse (unpack path)
+  let (sep, path'') = span isPathSeparator path'
+  let addSep = if null sep then id else (pathSeparator :)
+  pack (reverse (addSep path''))
+
+-- | Convert empty paths to the current directory, otherwise leave it
+-- unchanged.
+emptyToCurDir :: OsPath -> OsPath
+emptyToCurDir path
+  | path == mempty = os "."
+  | otherwise      = path
+
+-- | Similar to 'normalise' but empty paths stay empty.
+simplifyPosix :: OsPath -> OsPath
+simplifyPosix path
+  | path == mempty = mempty
+  | otherwise      = normalise path
+
+-- | Similar to 'normalise' but:
+--
+-- * empty paths stay empty,
+-- * parent dirs (@..@) are expanded, and
+-- * paths starting with @\\\\@ are preserved.
+--
+-- The goal is to preserve the meaning of paths better than 'normalise'.
+simplifyWindows :: OsPath -> OsPath
+simplifyWindows path
+  | path == mempty = mempty
+  | otherwise = case toChar <$> unpack drive' of
+      '\\' : '\\' : _ -> drive' <> subpath
+      _ -> simplifiedPath
+  where
+    simplifiedPath = joinDrive drive' subpath'
+    (drive, subpath) = splitDrive path
+    drive' = upperDrive (normaliseTrailingSep (normalisePathSeps drive))
+    subpath' = appendSep . avoidEmpty . prependSep . joinPath .
+               stripPardirs . expandDots . skipSeps .
+               splitDirectories $ subpath
+
+    upperDrive d = case unpack d of
+      c : k : s
+        | isAlpha (toChar c), toChar k == ':', all isPathSeparator s ->
+          -- unsafeFromChar is safe here since all characters are ASCII.
+          pack (unsafeFromChar (toUpper (toChar c)) : unsafeFromChar ':' : s)
+      _ -> d
+    skipSeps =
+      (pack <$>) .
+      filter (not . (`elem` (pure <$> pathSeparators))) .
+      (unpack <$>)
+    stripPardirs | pathIsAbsolute || subpathIsAbsolute = dropWhile (== os "..")
+                 | otherwise = id
+    prependSep | subpathIsAbsolute = (pack [pathSeparator] <>)
+               | otherwise = id
+    avoidEmpty | not pathIsAbsolute
+               , drive == mempty || hasTrailingPathSep -- prefer "C:" over "C:."
+                 = emptyToCurDir
+               | otherwise = id
+    appendSep p | hasTrailingPathSep, not (pathIsAbsolute && p == mempty)
+                  = addTrailingPathSeparator p
+                | otherwise = p
+    pathIsAbsolute = not (isRelative path)
+    subpathIsAbsolute = any isPathSeparator (take 1 (unpack subpath))
+    hasTrailingPathSep = hasTrailingPathSeparator subpath
+
+data WhetherFollow = NoFollow | FollowLinks deriving (Show)
+
+isNoFollow :: WhetherFollow -> Bool
+isNoFollow NoFollow    = True
+isNoFollow FollowLinks = False
+
+data FileType
+  = File
+  | SymbolicLink -- ^ POSIX: either file or directory link; Windows: file link
+  | Directory
+  | DirectoryLink -- ^ Windows only: directory link
+  deriving (Bounded, Enum, Eq, Ord, Read, Show)
+
+-- | Check whether the given 'FileType' is considered a directory by the
+-- operating system.  This affects the choice of certain functions
+-- e.g. 'System.Directory.removeDirectory' vs 'System.Directory.removeFile'.
+fileTypeIsDirectory :: FileType -> Bool
+fileTypeIsDirectory Directory     = True
+fileTypeIsDirectory DirectoryLink = True
+fileTypeIsDirectory _             = False
+
+-- | Return whether the given 'FileType' is a link.
+fileTypeIsLink :: FileType -> Bool
+fileTypeIsLink SymbolicLink  = True
+fileTypeIsLink DirectoryLink = True
+fileTypeIsLink _             = False
+
+data Permissions
+  = Permissions
+  { readable :: Bool
+  , writable :: Bool
+  , executable :: Bool
+  , searchable :: Bool
+  } deriving (Eq, Ord, Read, Show)
+
+withBinaryFile :: OsPath -> IOMode -> (Handle -> IO r) -> IO r
+withBinaryFile path mode =
+  bracket (File.openFileWithCloseOnExec path mode) hClose
+
+openTempFile' :: String -> OsPath -> OsString -> Bool -> CMode -> Bool
+              -> IO (OsPath, Handle)
+openTempFile' loc tmpDir template binary mode _cloExec =
+  File.openTempFile' loc tmpDir template binary mode
+#if MIN_VERSION_file_io(0, 2, 0)
+    _cloExec
+#endif
+
+-- | Copy data from one handle to another until end of file.
+copyHandleData :: Handle                -- ^ Source handle
+               -> Handle                -- ^ Destination handle
+               -> IO ()
+copyHandleData hFrom hTo =
+  (`ioeAddLocation` "copyData") `modifyIOError` do
+    allocaBytes bufferSize go
+  where
+    -- 128 KiB, as coreutils `cp` uses as of May 2014 (see ioblksize.h)
+    bufferSize = 131072
+    go buffer = do
+      count <- hGetBuf hFrom buffer bufferSize
+      when (count > 0) $ do
+        hPutBuf hTo buffer count
+        go buffer
+
+-- | Special directories for storing user-specific application data,
+-- configuration, and cache files, as specified by the
+-- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
+--
+-- Note: On Windows, 'XdgData' and 'XdgConfig' usually map to the same
+-- directory.
+--
+-- @since 1.2.3.0
+data XdgDirectory
+  = XdgData
+    -- ^ For data files (e.g. images).
+    -- It uses the @XDG_DATA_HOME@ environment variable.
+    -- On non-Windows systems, the default is @~\/.local\/share@.
+    -- On Windows, the default is @%APPDATA%@
+    -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).
+    -- Can be considered as the user-specific equivalent of @\/usr\/share@.
+  | XdgConfig
+    -- ^ For configuration files.
+    -- It uses the @XDG_CONFIG_HOME@ environment variable.
+    -- On non-Windows systems, the default is @~\/.config@.
+    -- On Windows, the default is @%APPDATA%@
+    -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming@).
+    -- Can be considered as the user-specific equivalent of @\/etc@.
+  | XdgCache
+    -- ^ For non-essential files (e.g. cache).
+    -- It uses the @XDG_CACHE_HOME@ environment variable.
+    -- On non-Windows systems, the default is @~\/.cache@.
+    -- On Windows, the default is @%LOCALAPPDATA%@
+    -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Local@).
+    -- Can be considered as the user-specific equivalent of @\/var\/cache@.
+  | XdgState
+   -- ^ For data that should persist between (application) restarts,
+   -- but that is not important or portable enough to the user that it
+   -- should be stored in 'XdgData'.
+   -- It uses the @XDG_STATE_HOME@ environment variable.
+   -- On non-Windows systems, the default is @~\/.local\/state@.  On
+   -- Windows, the default is @%LOCALAPPDATA%@
+   -- (e.g. @C:\/Users\//\<user\>/\/AppData\/Local@).
+   --
+   -- @since 1.3.7.0
+  deriving (Bounded, Enum, Eq, Ord, Read, Show)
+
+-- | Search paths for various application data, as specified by the
+-- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
+--
+-- The list of paths is split using 'System.FilePath.searchPathSeparator',
+-- which on Windows is a semicolon.
+--
+-- Note: On Windows, 'XdgDataDirs' and 'XdgConfigDirs' usually yield the same
+-- result.
+--
+-- @since 1.3.2.0
+data XdgDirectoryList
+  = XdgDataDirs
+    -- ^ For data files (e.g. images).
+    -- It uses the @XDG_DATA_DIRS@ environment variable.
+    -- On non-Windows systems, the default is @\/usr\/local\/share\/@ and
+    -- @\/usr\/share\/@.
+    -- On Windows, the default is @%PROGRAMDATA%@ or @%ALLUSERSPROFILE%@
+    -- (e.g. @C:\/ProgramData@).
+  | XdgConfigDirs
+    -- ^ For configuration files.
+    -- It uses the @XDG_CONFIG_DIRS@ environment variable.
+    -- On non-Windows systems, the default is @\/etc\/xdg@.
+    -- On Windows, the default is @%PROGRAMDATA%@ or @%ALLUSERSPROFILE%@
+    -- (e.g. @C:\/ProgramData@).
+  deriving (Bounded, Enum, Eq, Ord, Read, Show)
diff --git a/System/Directory/Internal/Config.hs b/System/Directory/Internal/Config.hs
--- a/System/Directory/Internal/Config.hs
+++ b/System/Directory/Internal/Config.hs
@@ -1,13 +1,10 @@
 {-# LANGUAGE CPP #-}
-#include <HsDirectoryConfig.h>
 module System.Directory.Internal.Config where
+#include <HsDirectoryConfig.h>
+import System.Directory.Internal.Common
 
--- | Filename extension for executable files (including the dot if any)
---   (usually @\"\"@ on POSIX systems and @\".exe\"@ on Windows or OS\/2).
---
--- @since 1.2.4.0
-exeExtension :: String
-exeExtension = EXE_EXTENSION
+exeExtension :: OsString
+exeExtension = os EXE_EXTENSION
 -- We avoid using #const_str from hsc because it breaks cross-compilation
 -- builds, so we use this ugly workaround where we simply paste the C string
 -- literal directly in here.  This will probably break if the EXE_EXTENSION
diff --git a/System/Directory/Internal/Posix.hsc b/System/Directory/Internal/Posix.hsc
--- a/System/Directory/Internal/Posix.hsc
+++ b/System/Directory/Internal/Posix.hsc
@@ -1,12 +1,99 @@
+{-# LANGUAGE CApiFFI #-}
 module System.Directory.Internal.Posix where
 #include <HsDirectoryConfig.h>
-#ifndef mingw32_HOST_OS
+#if !defined(mingw32_HOST_OS)
+#include <fcntl.h>
 #ifdef HAVE_LIMITS_H
 # include <limits.h>
 #endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
 import Prelude ()
 import System.Directory.Internal.Prelude
+#ifdef HAVE_UTIMENSAT
+import System.Directory.Internal.C_utimensat
+#endif
+import System.Directory.Internal.Common
+import System.Directory.Internal.Config (exeExtension)
+import Data.Time (UTCTime)
+import Data.Time.Clock.POSIX (POSIXTime)
+import System.OsPath ((</>), isRelative, splitSearchPath)
+import System.OsString.Internal.Types (OsString(OsString, getOsString))
+import qualified Data.Time.Clock.POSIX as POSIXTime
+import qualified System.OsPath.Internal as OsPath
+import qualified System.Posix.Directory.Fd as Posix
+import qualified System.Posix.Directory.PosixPath as Posix
+import qualified System.Posix.Env.PosixString as Posix
+import qualified System.Posix.Files as Posix (FileStatus(..))
+import qualified System.Posix.Files.PosixString as Posix
+import qualified System.Posix.Internals as Posix (CStat)
+import qualified System.Posix.IO.PosixString as Posix
+import qualified System.Posix.PosixPath.FilePath as Posix
+import qualified System.Posix.Types as Posix
+import qualified System.Posix.User.ByteString as Posix
 
+c_AT_FDCWD :: Posix.Fd
+c_AT_FDCWD = Posix.Fd (#const AT_FDCWD)
+
+c_AT_SYMLINK_NOFOLLOW :: CInt
+c_AT_SYMLINK_NOFOLLOW = (#const AT_SYMLINK_NOFOLLOW)
+
+atWhetherFollow :: WhetherFollow -> CInt
+atWhetherFollow NoFollow    = c_AT_SYMLINK_NOFOLLOW
+atWhetherFollow FollowLinks = 0
+
+defaultOpenFlags :: Posix.OpenFileFlags
+defaultOpenFlags =
+  Posix.defaultFileFlags
+  { Posix.noctty = True
+  , Posix.nonBlock = True
+  , Posix.cloexec = True
+  }
+
+type RawHandle = Posix.Fd
+
+openRaw :: WhetherFollow -> Maybe RawHandle -> OsPath -> IO RawHandle
+openRaw whetherFollow dir (OsString path) =
+  Posix.openFdAt dir path Posix.ReadOnly flags
+  where
+    flags = defaultOpenFlags { Posix.nofollow = isNoFollow whetherFollow }
+
+closeRaw :: RawHandle -> IO ()
+closeRaw = Posix.closeFd
+
+createDirectoryInternal :: OsPath -> IO ()
+createDirectoryInternal (OsString path) = Posix.createDirectory path 0o777
+
+foreign import ccall "unistd.h unlinkat" c_unlinkat
+  :: Posix.Fd -> CString -> CInt -> IO CInt
+
+removePathAt :: FileType -> Maybe RawHandle -> OsPath -> IO ()
+removePathAt ty dir (OsString path) =
+  Posix.withFilePath path $ \ pPath -> do
+    Posix.throwErrnoPathIfMinus1_ "unlinkat" path
+      (c_unlinkat (fromMaybe c_AT_FDCWD dir) pPath flag)
+    pure ()
+  where
+    flag | fileTypeIsDirectory ty = (#const AT_REMOVEDIR)
+         | otherwise              = 0
+
+removePathInternal :: Bool -> OsPath -> IO ()
+removePathInternal True  = Posix.removeDirectory . getOsString
+removePathInternal False = Posix.removeLink . getOsString
+
+renamePathInternal :: OsPath -> OsPath -> IO ()
+renamePathInternal (OsString p1) (OsString p2) = Posix.rename p1 p2
+
+-- On POSIX, the removability of a file is only affected by the attributes of
+-- the containing directory.
+filesAlwaysRemovable :: Bool
+filesAlwaysRemovable = True
+
+-- | On POSIX, equivalent to 'simplifyPosix'.
+simplify :: OsPath -> OsPath
+simplify = simplifyPosix
+
 -- we use the 'free' from the standard library here since it's not entirely
 -- clear whether Haskell's 'free' corresponds to the same one
 foreign import ccall unsafe "free" c_free :: Ptr a -> IO ()
@@ -16,14 +103,30 @@
 c_PATH_MAX | c_PATH_MAX' > toInteger maxValue = Nothing
            | otherwise                        = Just (fromInteger c_PATH_MAX')
   where c_PATH_MAX' = (#const PATH_MAX)
-        maxValue    = maxBound `asTypeOf` case c_PATH_MAX of ~(Just x) -> x
+        maxValue = maxBound `asTypeInMaybe` c_PATH_MAX
+        asTypeInMaybe :: a -> Maybe a -> a
+        asTypeInMaybe = const
 #else
 c_PATH_MAX = Nothing
 #endif
 
-foreign import ccall "realpath" c_realpath
-  :: CString -> CString -> IO CString
+#if !defined(HAVE_REALPATH)
 
+c_realpath :: CString -> CString -> IO CString
+c_realpath _ _ =
+  throwIO
+    (mkIOError
+      UnsupportedOperation
+      "platform does not support realpath"
+      Nothing
+      Nothing)
+
+#else
+
+foreign import ccall "realpath" c_realpath :: CString -> CString -> IO CString
+
+#endif
+
 withRealpath :: CString -> (CString -> IO a) -> IO a
 withRealpath path action = case c_PATH_MAX of
   Nothing ->
@@ -34,5 +137,302 @@
     -- allocate one extra just to be safe
     allocaBytes (pathMax + 1) (realpath >=> action)
   where realpath = throwErrnoIfNull "" . c_realpath path
+
+realPath :: OsPath -> IO OsPath
+realPath (OsString path') =
+  Posix.withFilePath path'
+    (`withRealpath` ((OsString <$>) . Posix.peekFilePath))
+
+canonicalizePathSimplify :: OsPath -> IO OsPath
+canonicalizePathSimplify = pure
+
+findExecutablesLazyInternal :: ([OsPath] -> OsString -> ListT IO OsPath)
+                            -> OsString
+                            -> ListT IO OsPath
+findExecutablesLazyInternal findExecutablesInDirectoriesLazy binary =
+  liftJoinListT $ do
+    path <- getPath
+    pure (findExecutablesInDirectoriesLazy path binary)
+
+getPath :: IO [OsPath]
+getPath = splitSearchPath <$> getEnvOs (os "PATH")
+
+exeExtensionInternal :: OsString
+exeExtensionInternal = exeExtension
+
+openDirFromFd :: Posix.Fd -> IO Posix.DirStream
+openDirFromFd fd = Posix.unsafeOpenDirStreamFd =<< Posix.dup fd
+
+readDirStreamToEnd :: Posix.DirStream -> IO [OsPath]
+readDirStreamToEnd stream = loop id
+  where
+    loop acc = do
+      e <- Posix.readDirStream stream
+      if e == mempty
+        then pure (acc [])
+        else loop (acc . (OsString e :))
+
+readDirToEnd :: RawHandle -> IO [OsPath]
+readDirToEnd fd =
+  bracket (openDirFromFd fd) Posix.closeDirStream readDirStreamToEnd
+
+getDirectoryContentsInternal :: OsPath -> IO [OsPath]
+getDirectoryContentsInternal (OsString path) =
+  bracket (Posix.openDirStream path) Posix.closeDirStream readDirStreamToEnd
+
+getCurrentDirectoryInternal :: IO OsPath
+getCurrentDirectoryInternal = OsString <$> Posix.getWorkingDirectory
+
+-- | Convert a path into an absolute path.  If the given path is relative, the
+-- current directory is prepended and the path may or may not be simplified.
+-- If the path is already absolute, the path is returned unchanged.  The
+-- function preserves the presence or absence of the trailing path separator.
+--
+-- If the path is already absolute, the operation never fails.  Otherwise, the
+-- operation may throw exceptions.
+--
+-- Empty paths are treated as the current directory.
+prependCurrentDirectory :: OsPath -> IO OsPath
+prependCurrentDirectory path
+  | isRelative path =
+    ((`ioeAddLocation` "prependCurrentDirectory") .
+     (`ioeSetOsPath` path)) `modifyIOError` do
+      (</> path) <$> getCurrentDirectoryInternal
+  | otherwise = pure path
+
+setCurrentDirectoryInternal :: OsPath -> IO ()
+setCurrentDirectoryInternal = Posix.changeWorkingDirectory . getOsString
+
+linkToDirectoryIsDirectory :: Bool
+linkToDirectoryIsDirectory = False
+
+createHardLink :: OsPath -> OsPath -> IO ()
+createHardLink (OsString p1) (OsString p2) = Posix.createLink p1 p2
+
+createSymbolicLink :: Bool -> OsPath -> OsPath -> IO ()
+createSymbolicLink _ (OsString p1) (OsString p2) =
+  Posix.createSymbolicLink p1 p2
+
+readSymbolicLink :: OsPath -> IO OsPath
+readSymbolicLink = (OsString <$>) . Posix.readSymbolicLink . getOsString
+
+type Metadata = Posix.FileStatus
+
+foreign import capi "sys/stat.h fstatat" c_fstatat
+  :: Posix.Fd -> CString -> Ptr Posix.CStat -> CInt -> IO CInt
+
+getMetadataAt :: WhetherFollow -> Maybe RawHandle -> OsPath -> IO Metadata
+getMetadataAt whetherFollow dir (OsString path) =
+  Posix.withFilePath path $ \ pPath -> do
+    stat <- mallocForeignPtrBytes (#const sizeof(struct stat))
+    withForeignPtr stat $ \ pStat -> do
+      Posix.throwErrnoPathIfMinus1_ "fstatat" path $ do
+        c_fstatat (fromMaybe c_AT_FDCWD dir) pPath pStat flags
+    pure (Posix.FileStatus stat)
+  where
+    flags = atWhetherFollow whetherFollow
+
+getSymbolicLinkMetadata :: OsPath -> IO Metadata
+getSymbolicLinkMetadata = Posix.getSymbolicLinkStatus . getOsString
+
+getFileMetadata :: OsPath -> IO Metadata
+getFileMetadata = Posix.getFileStatus . getOsString
+
+fileTypeFromMetadata :: Metadata -> FileType
+fileTypeFromMetadata stat
+  | isLink    = SymbolicLink
+  | isDir     = Directory
+  | otherwise = File
+  where
+    isLink = Posix.isSymbolicLink stat
+    isDir  = Posix.isDirectory stat
+
+fileSizeFromMetadata :: Metadata -> Integer
+fileSizeFromMetadata = fromIntegral . Posix.fileSize
+
+accessTimeFromMetadata :: Metadata -> UTCTime
+accessTimeFromMetadata =
+  POSIXTime.posixSecondsToUTCTime . Posix.accessTimeHiRes
+
+modificationTimeFromMetadata :: Metadata -> UTCTime
+modificationTimeFromMetadata =
+  POSIXTime.posixSecondsToUTCTime . Posix.modificationTimeHiRes
+
+type Mode = Posix.FileMode
+
+modeFromMetadata :: Metadata -> Mode
+modeFromMetadata = Posix.fileMode
+
+allWriteMode :: Posix.FileMode
+allWriteMode =
+  Posix.ownerWriteMode .|.
+  Posix.groupWriteMode .|.
+  Posix.otherWriteMode
+
+hasWriteMode :: Mode -> Bool
+hasWriteMode m = m .&. allWriteMode /= 0
+
+setWriteMode :: Bool -> Mode -> Mode
+setWriteMode False m = m .&. complement allWriteMode
+setWriteMode True  m = m .|. allWriteMode
+
+setForceRemoveMode :: Mode -> Mode
+setForceRemoveMode m = m .|. Posix.ownerModes
+
+foreign import capi "sys/stat.h fchmodat" c_fchmodat
+  :: Posix.Fd -> CString -> Posix.FileMode -> CInt -> IO CInt
+
+setModeAt :: Maybe RawHandle -> OsPath -> Mode -> IO ()
+setModeAt dir (OsString path) mode = do
+  Posix.withFilePath path $ \ pPath ->
+    Posix.throwErrnoPathIfMinus1_ "fchmodat" path $ do
+      c_fchmodat (fromMaybe c_AT_FDCWD dir) pPath mode 0
+
+setFileMode :: OsPath -> Mode -> IO ()
+setFileMode = Posix.setFileMode . getOsString
+
+setFilePermissions :: OsPath -> Mode -> IO ()
+setFilePermissions = setFileMode
+
+getAccessPermissions :: OsPath -> IO Permissions
+getAccessPermissions path = do
+  m <- getFileMetadata path
+  let isDir = fileTypeIsDirectory (fileTypeFromMetadata m)
+  let OsString path' = path
+  r <- Posix.fileAccess path' True  False False
+  w <- Posix.fileAccess path' False True  False
+  x <- Posix.fileAccess path' False False True
+  pure Permissions
+       { readable   = r
+       , writable   = w
+       , executable = x && not isDir
+       , searchable = x && isDir
+       }
+
+setAccessPermissions :: OsPath -> Permissions -> IO ()
+setAccessPermissions path (Permissions r w e s) = do
+  m <- getFileMetadata path
+  setFileMode path (modifyBit (e || s) Posix.ownerExecuteMode .
+                    modifyBit w Posix.ownerWriteMode .
+                    modifyBit r Posix.ownerReadMode .
+                    modeFromMetadata $ m)
+  where
+    modifyBit :: Bool -> Posix.FileMode -> Posix.FileMode -> Posix.FileMode
+    modifyBit False b m = m .&. complement b
+    modifyBit True  b m = m .|. b
+
+copyOwnerFromStatus :: Posix.FileStatus -> OsPath -> IO ()
+copyOwnerFromStatus st (OsString dst) = do
+  Posix.setOwnerAndGroup dst (Posix.fileOwner st) (-1)
+
+copyGroupFromStatus :: Posix.FileStatus -> OsPath -> IO ()
+copyGroupFromStatus st (OsString dst) = do
+  Posix.setOwnerAndGroup dst (-1) (Posix.fileGroup st)
+
+tryCopyOwnerAndGroupFromStatus :: Posix.FileStatus -> OsPath -> IO ()
+tryCopyOwnerAndGroupFromStatus st dst = do
+  ignoreIOExceptions (copyOwnerFromStatus st dst)
+  ignoreIOExceptions (copyGroupFromStatus st dst)
+
+-- | Truncate the destination file and then copy the contents of the source
+-- file to the destination file.  If the destination file already exists, its
+-- attributes shall remain unchanged.  Otherwise, its attributes are reset to
+-- the defaults.
+copyFileContents :: OsPath              -- ^ Source filename
+                 -> OsPath              -- ^ Destination filename
+                 -> IO ()
+copyFileContents fromFPath toFPath =
+  (`ioeAddLocation` "copyFileContents") `modifyIOError` do
+    withBinaryFile toFPath WriteMode $ \ hTo -> do
+      withBinaryFile fromFPath ReadMode $ \ hFrom -> do
+        copyHandleData hFrom hTo
+
+copyFileWithMetadataInternal :: (Metadata -> OsPath -> IO ())
+                             -> (Metadata -> OsPath -> IO ())
+                             -> OsPath
+                             -> OsPath
+                             -> IO ()
+copyFileWithMetadataInternal copyPermissionsFromMetadata
+                             copyTimesFromMetadata
+                             src
+                             dst = do
+  st <- Posix.getFileStatus (getOsString src)
+  copyFileContents src dst
+  tryCopyOwnerAndGroupFromStatus st dst
+  copyPermissionsFromMetadata st dst
+  copyTimesFromMetadata st dst
+
+setTimes :: OsPath -> (Maybe POSIXTime, Maybe POSIXTime) -> IO ()
+#ifdef HAVE_UTIMENSAT
+setTimes (OsString path') (atime', mtime') =
+  Posix.withFilePath path' $ \ path'' ->
+  withArray [ maybe utimeOmit toCTimeSpec atime'
+            , maybe utimeOmit toCTimeSpec mtime' ] $ \ times ->
+  Posix.throwErrnoPathIfMinus1_ "" path' $
+    c_utimensat c_AT_FDCWD path'' times 0
+#else
+setTimes (OsString path') (Just atime', Just mtime') =
+  Posix.setFileTimesHiRes path' atime' mtime'
+setTimes (OsString path') (atime', mtime') = do
+  m <- getFileMetadata (OsString path')
+  let atimeOld = accessTimeFromMetadata m
+  let mtimeOld = modificationTimeFromMetadata m
+  Posix.setFileTimesHiRes path'
+    (fromMaybe (POSIXTime.utcTimeToPOSIXSeconds atimeOld) atime')
+    (fromMaybe (POSIXTime.utcTimeToPOSIXSeconds mtimeOld) mtime')
+#endif
+
+lookupEnvOs :: OsString -> IO (Maybe OsString)
+lookupEnvOs (OsString name) = (OsString <$>) <$> Posix.getEnv name
+
+getEnvOs :: OsString -> IO OsString
+getEnvOs name = do
+  env <- lookupEnvOs name
+  case env of
+    Nothing ->
+      throwIO $
+        mkIOError
+          doesNotExistErrorType
+          ("env var " <> show name <> " not found")
+          Nothing
+          Nothing
+    Just value -> pure value
+
+-- | $HOME is preferred, because the user has control over it. However, POSIX
+-- doesn't define it as a mandatory variable, so fall back to `getpwuid_r`.
+getHomeDirectoryInternal :: IO OsPath
+getHomeDirectoryInternal = do
+  e <- lookupEnvOs (os "HOME")
+  case e of
+    Just fp -> pure fp
+    Nothing ->
+      OsPath.fromBytes . Posix.homeDirectory =<<
+        Posix.getUserEntryForID =<<
+        Posix.getEffectiveUserID
+
+getXdgDirectoryFallback :: IO OsPath -> XdgDirectory -> IO OsPath
+getXdgDirectoryFallback getHomeDirectory xdgDir = do
+  (<$> getHomeDirectory) $ flip (</>) $ case xdgDir of
+    XdgData   -> os ".local/share"
+    XdgConfig -> os ".config"
+    XdgCache  -> os ".cache"
+    XdgState  -> os ".local/state"
+
+getXdgDirectoryListFallback :: XdgDirectoryList -> IO [OsPath]
+getXdgDirectoryListFallback xdgDirs =
+  pure $ case xdgDirs of
+    XdgDataDirs   -> [os "/usr/local/share/", os "/usr/share/"]
+    XdgConfigDirs -> [os "/etc/xdg"]
+
+getAppUserDataDirectoryInternal :: OsPath -> IO OsPath
+getAppUserDataDirectoryInternal appName =
+  (\ home -> home <> (os "/" <> os "." <> appName)) <$> getHomeDirectoryInternal
+
+getUserDocumentsDirectoryInternal :: IO OsPath
+getUserDocumentsDirectoryInternal = getHomeDirectoryInternal
+
+getTemporaryDirectoryInternal :: IO OsPath
+getTemporaryDirectoryInternal =
+  fromMaybe (os "/tmp") <$> lookupEnvOs (os "TMPDIR")
 
 #endif
diff --git a/System/Directory/Internal/Prelude.hs b/System/Directory/Internal/Prelude.hs
--- a/System/Directory/Internal/Prelude.hs
+++ b/System/Directory/Internal/Prelude.hs
@@ -1,11 +1,12 @@
-{-# LANGUAGE CPP #-}
 {-# OPTIONS_HADDOCK hide #-}
+-- |
+-- Stability: unstable
+-- Portability: portable
+--
+-- Internal modules are always subject to change from version to version.
+
 module System.Directory.Internal.Prelude
   ( module Prelude
-#if !MIN_VERSION_base(4, 8, 0)
-  , module Control.Applicative
-  , module Data.Functor
-#endif
   , module Control.Arrow
   , module Control.Concurrent
   , module Control.Exception
@@ -26,20 +27,11 @@
   , module System.Exit
   , module System.IO
   , module System.IO.Error
-  , module System.Posix.Internals
   , module System.Posix.Types
   , module System.Timeout
   , Void
   ) where
-#if !MIN_VERSION_base(4, 6, 0)
-import Prelude hiding (catch)
-#endif
-#if MIN_VERSION_base(4, 8, 0)
 import Data.Void (Void)
-#else
-import Control.Applicative ((<*>), pure)
-import Data.Functor ((<$>), (<$))
-#endif
 import Control.Arrow (second)
 import Control.Concurrent
   ( forkIO
@@ -48,11 +40,14 @@
   , putMVar
   , readMVar
   , takeMVar
+  , forkFinally
   )
 import Control.Exception
-  ( SomeException
+  ( Exception(displayException)
+  , SomeException
   , bracket
   , bracket_
+  , bracketOnError
   , catch
   , finally
   , mask
@@ -60,10 +55,10 @@
   , throwIO
   , try
   )
-import Control.Monad ((>=>), (<=<), unless, when, replicateM_)
+import Control.Monad ((>=>), (<=<), unless, when, replicateM, replicateM_)
 import Data.Bits ((.&.), (.|.), complement)
-import Data.Char (isAlpha, isAscii, toLower)
-import Data.Foldable (for_, traverse_)
+import Data.Char (isAlpha, isAscii, toLower, toUpper)
+import Data.Foldable (for_, sequenceA_)
 import Data.Function (on)
 import Data.Maybe (catMaybes, fromMaybe, maybeToList)
 import Data.Monoid ((<>), mconcat, mempty)
@@ -85,11 +80,13 @@
   , allocaArray
   , allocaBytes
   , allocaBytesAligned
+  , mallocForeignPtrBytes
   , maybeWith
   , nullPtr
   , plusPtr
   , with
   , withArray
+  , withForeignPtr
   )
 import Foreign.C
   ( CInt(..)
@@ -101,24 +98,20 @@
   , CUShort(..)
   , CWString
   , CWchar(..)
-  , peekCString
-  , peekCWStringLen
   , throwErrnoIfMinus1Retry_
   , throwErrnoIfMinus1_
   , throwErrnoIfNull
-  , throwErrnoPathIfMinus1_
-  , withCString
-  , withCWString
   )
 import GHC.IO.Exception
   ( IOErrorType
     ( InappropriateType
+    , InvalidArgument
     , OtherError
     , UnsupportedOperation
     )
   )
 import GHC.IO.Encoding (getFileSystemEncoding)
-import System.Environment (getArgs, getEnv)
+import System.Environment (getArgs)
 import System.Exit (exitFailure)
 import System.IO
   ( Handle
@@ -129,14 +122,14 @@
   , hPutBuf
   , hPutStr
   , hPutStrLn
-  , openBinaryTempFile
   , stderr
   , stdout
-  , withBinaryFile
   )
 import System.IO.Error
   ( IOError
   , catchIOError
+  , doesNotExistErrorType
+  , illegalOperationErrorType
   , ioeGetErrorString
   , ioeGetErrorType
   , ioeGetLocation
@@ -145,6 +138,7 @@
   , ioeSetLocation
   , isAlreadyExistsError
   , isDoesNotExistError
+  , isIllegalOperation
   , isPermissionError
   , mkIOError
   , modifyIOError
@@ -152,21 +146,5 @@
   , tryIOError
   , userError
   )
-import System.Posix.Internals
-  ( CStat
-  , c_stat
-  , withFilePath
-  , s_isdir
-  , sizeof_stat
-  , st_mode
-  , st_size
-  )
-import System.Posix.Types (CMode(..), EpochTime, FileMode)
+import System.Posix.Types (CMode, EpochTime)
 import System.Timeout (timeout)
-
-#if !MIN_VERSION_base(4, 8, 0)
-data Void = Void
-
-_unusedVoid :: Void
-_unusedVoid = Void
-#endif
diff --git a/System/Directory/Internal/Windows.hsc b/System/Directory/Internal/Windows.hsc
--- a/System/Directory/Internal/Windows.hsc
+++ b/System/Directory/Internal/Windows.hsc
@@ -1,79 +1,156 @@
 {-# LANGUAGE CPP #-}
 module System.Directory.Internal.Windows where
 #include <HsDirectoryConfig.h>
-#ifdef mingw32_HOST_OS
-##if defined i386_HOST_ARCH
+#if defined(mingw32_HOST_OS)
+##if defined(i386_HOST_ARCH)
 ## define WINAPI stdcall
-##elif defined x86_64_HOST_ARCH
+##elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
 ## define WINAPI ccall
 ##else
 ## error unknown architecture
 ##endif
 #include <shlobj.h>
 #include <windows.h>
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
+#include <HsBaseConfig.h>
+#include <System/Directory/Internal/windows_ext.h>
 import Prelude ()
 import System.Directory.Internal.Prelude
-import System.FilePath (isRelative, normalise, splitDirectories)
-import qualified System.Win32 as Win32
-
-win32_cSIDL_LOCAL_APPDATA :: Win32.CSIDL
-#if MIN_VERSION_Win32(2, 3, 1)
-win32_cSIDL_LOCAL_APPDATA = Win32.cSIDL_LOCAL_APPDATA
-#else
-win32_cSIDL_LOCAL_APPDATA = (#const CSIDL_LOCAL_APPDATA)
+import System.Directory.Internal.Common
+import System.Directory.Internal.Config (exeExtension)
+import Data.Time (UTCTime)
+import Data.Time.Clock.POSIX (POSIXTime, posixSecondsToUTCTime)
+#ifdef __IO_MANAGER_WINIO__
+import GHC.IO.SubSystem (IoSubSystem(IoPOSIX, IoNative), ioSubSystem)
 #endif
+import System.OsPath
+  ( (</>)
+  , hasExtension
+  , isExtensionOf
+  , isPathSeparator
+  , isRelative
+  , pack
+  , pathSeparator
+  , splitDirectories
+  , splitSearchPath
+  , takeExtension
+  , toChar
+  , unpack
+  )
+import System.OsPath.Types (WindowsPath, WindowsString)
+import System.OsString.Internal.Types (OsString(OsString, getOsString))
+import qualified Data.List as List
+import qualified System.Win32.WindowsString.File as Win32
+import qualified System.Win32.WindowsString.Info as Win32
+import qualified System.Win32.WindowsString.Shell as Win32
+import qualified System.Win32.WindowsString.Time as Win32
+import qualified System.Win32.WindowsString.Types as Win32
+import qualified System.Win32.WindowsString.Console as Win32
 
-win32_fILE_ATTRIBUTE_REPARSE_POINT :: Win32.FileAttributeOrFlag
-win32_fILE_ATTRIBUTE_REPARSE_POINT = (#const FILE_ATTRIBUTE_REPARSE_POINT)
+type RawHandle = OsPath
 
-win32_fILE_SHARE_DELETE :: Win32.ShareMode
-#if MIN_VERSION_Win32(2, 3, 1)
-win32_fILE_SHARE_DELETE = Win32.fILE_SHARE_DELETE -- added in 2.3.0.2
-#else
-win32_fILE_SHARE_DELETE = (#const FILE_SHARE_DELETE)
-#endif
+pathAt :: Maybe RawHandle -> OsPath -> OsPath
+pathAt dir path = fromMaybe mempty dir </> path
 
-win32_getLongPathName, win32_getShortPathName :: FilePath -> IO FilePath
-#if MIN_VERSION_Win32(2, 4, 0)
-win32_getLongPathName = Win32.getLongPathName
-win32_getShortPathName = Win32.getShortPathName
-#else
-win32_getLongPathName path =
-  modifyIOError ((`ioeSetLocation` "GetLongPathName") .
-                 (`ioeSetFileName` path)) $ do
-    withCWString path $ \ ptrPath -> do
-      getPathNameWith (c_GetLongPathName ptrPath)
+openRaw :: WhetherFollow -> Maybe RawHandle -> OsPath -> IO RawHandle
+openRaw _ dir path = pure (pathAt dir path)
 
-win32_getShortPathName path =
-  modifyIOError ((`ioeSetLocation` "GetShortPathName") .
-                 (`ioeSetFileName` path)) $ do
-    withCWString path $ \ ptrPath -> do
-      getPathNameWith (c_GetShortPathName ptrPath)
+closeRaw :: RawHandle -> IO ()
+closeRaw _ = pure ()
 
-foreign import WINAPI unsafe "windows.h GetLongPathNameW"
-  c_GetLongPathName
-    :: Ptr CWchar
-    -> Ptr CWchar
-    -> Win32.DWORD
-    -> IO Win32.DWORD
+lookupEnvOs :: OsString -> IO (Maybe OsString)
+lookupEnvOs (OsString name) = (OsString <$>) <$> Win32.getEnv name
 
-foreign import WINAPI unsafe "windows.h GetShortPathNameW"
-  c_GetShortPathName
-    :: Ptr CWchar
-    -> Ptr CWchar
-    -> Win32.DWORD
-    -> IO Win32.DWORD
-#endif
+getEnvOs :: OsString -> IO OsString
+getEnvOs name = do
+  env <- lookupEnvOs name
+  case env of
+    Nothing ->
+      throwIO $
+        mkIOError
+          doesNotExistErrorType
+          ("env var " <> show name <> " not found")
+          Nothing
+          Nothing
+    Just value -> pure value
 
-win32_getFinalPathNameByHandle :: Win32.HANDLE -> Win32.DWORD -> IO FilePath
-win32_getFinalPathNameByHandle _h _flags =
-  modifyIOError (`ioeSetLocation` "GetFinalPathNameByHandle") $ do
+-- | Get the contents of the @PATH@ environment variable.
+getPath :: IO [OsPath]
+getPath = splitSearchPath <$> getEnvOs (os "PATH")
+
+createDirectoryInternal :: OsPath -> IO ()
+createDirectoryInternal path =
+  (`ioeSetOsPath` path) `modifyIOError` do
+    path' <- furnishPath path
+    Win32.createDirectory path' Nothing
+
+removePathAt :: FileType -> Maybe RawHandle -> OsPath -> IO ()
+removePathAt ty dir path = removePathInternal isDir (pathAt dir path)
+  where isDir = fileTypeIsDirectory ty
+
+removePathInternal :: Bool -> OsPath -> IO ()
+removePathInternal isDir path =
+  (`ioeSetOsPath` path) `modifyIOError` do
+    furnishPath path
+      >>= if isDir then Win32.removeDirectory else Win32.deleteFile
+
+renamePathInternal :: OsPath -> OsPath -> IO ()
+renamePathInternal opath npath =
+  (`ioeSetOsPath` opath) `modifyIOError` do
+    opath' <- furnishPath opath
+    npath' <- furnishPath npath
+    Win32.moveFileEx opath' (Just npath') Win32.mOVEFILE_REPLACE_EXISTING
+
+-- On Windows, the removability of a file may be affected by the attributes of
+-- the file itself.
+filesAlwaysRemovable :: Bool
+filesAlwaysRemovable = False
+
+copyFileWithMetadataInternal :: (Metadata -> OsPath -> IO ())
+                             -> (Metadata -> OsPath -> IO ())
+                             -> OsPath
+                             -> OsPath
+                             -> IO ()
+copyFileWithMetadataInternal _ _ src dst =
+  (`ioeSetOsPath` src) `modifyIOError` do
+    src' <- furnishPath src
+    dst' <- furnishPath dst
+    Win32.copyFile src' dst' False
+
+win32_cSIDL_COMMON_APPDATA :: Win32.CSIDL
+win32_cSIDL_COMMON_APPDATA = (#const CSIDL_COMMON_APPDATA)
+
+win32_eRROR_ENVVAR_NOT_FOUND :: Win32.ErrCode
+win32_eRROR_ENVVAR_NOT_FOUND = (#const ERROR_ENVVAR_NOT_FOUND)
+
+win32_eRROR_INVALID_FUNCTION :: Win32.ErrCode
+win32_eRROR_INVALID_FUNCTION = (#const ERROR_INVALID_FUNCTION)
+
+win32_eRROR_INVALID_PARAMETER :: Win32.ErrCode
+win32_eRROR_INVALID_PARAMETER = (#const ERROR_INVALID_PARAMETER)
+
+win32_eRROR_PRIVILEGE_NOT_HELD :: Win32.ErrCode
+win32_eRROR_PRIVILEGE_NOT_HELD = (#const ERROR_PRIVILEGE_NOT_HELD)
+
+win32_sYMBOLIC_LINK_FLAG_DIRECTORY :: Win32.DWORD
+win32_sYMBOLIC_LINK_FLAG_DIRECTORY = 0x1
+
+win32_sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE :: Win32.DWORD
+win32_sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2
+
+maxShareMode :: Win32.ShareMode
+maxShareMode =
+  Win32.fILE_SHARE_DELETE .|.
+  Win32.fILE_SHARE_READ   .|.
+  Win32.fILE_SHARE_WRITE
+
+win32_getFinalPathNameByHandle :: Win32.HANDLE -> Win32.DWORD -> IO WindowsPath
 #ifdef HAVE_GETFINALPATHNAMEBYHANDLEW
-    getPathNameWith $ \ ptr len -> do
-      c_GetFinalPathNameByHandle _h ptr len _flags
+win32_getFinalPathNameByHandle h flags = do
+  result <- peekTStringWith (#const MAX_PATH) $ \ ptr len -> do
+    c_GetFinalPathNameByHandle h ptr len flags
+  case result of
+    Left errCode -> Win32.failWith "GetFinalPathNameByHandle" errCode
+    Right path -> pure path
 
 foreign import WINAPI unsafe "windows.h GetFinalPathNameByHandleW"
   c_GetFinalPathNameByHandle
@@ -84,96 +161,571 @@
     -> IO Win32.DWORD
 
 #else
-    throwIO (mkIOError UnsupportedOperation
-             "platform does not support GetFinalPathNameByHandle"
-             Nothing Nothing)
+win32_getFinalPathNameByHandle _ _ = throwIO $
+  mkIOError
+    UnsupportedOperation
+    "platform does not support GetFinalPathNameByHandle"
+    Nothing
+    Nothing
 #endif
 
-getFinalPathName :: FilePath -> IO FilePath
+getFinalPathName :: OsPath -> IO OsPath
 getFinalPathName =
-  (fromExtendedLengthPath <$>) . rawGetFinalPathName . toExtendedLengthPath
+  (fromExtendedLengthPath <$>) .
+  rawGetFinalPathName .
+  toExtendedLengthPath
   where
 #ifdef HAVE_GETFINALPATHNAMEBYHANDLEW
     rawGetFinalPathName path = do
-      let open = Win32.createFile path 0 shareMode Nothing
+      let open = Win32.createFile path 0 maxShareMode Nothing
                  Win32.oPEN_EXISTING Win32.fILE_FLAG_BACKUP_SEMANTICS Nothing
       bracket open Win32.closeHandle $ \ h -> do
         win32_getFinalPathNameByHandle h 0
-    shareMode =
-      win32_fILE_SHARE_DELETE .|.
-      Win32.fILE_SHARE_READ   .|.
-      Win32.fILE_SHARE_WRITE
 #else
-    rawGetFinalPathName = win32_getLongPathName <=< win32_getShortPathName
+    rawGetFinalPathName = Win32.getLongPathName <=< Win32.getShortPathName
 #endif
 
--- | Add the @"\\\\?\\"@ prefix if necessary or possible.
--- The path remains unchanged if the prefix is not added.
-toExtendedLengthPath :: FilePath -> FilePath
-toExtendedLengthPath path
-  | isRelative path = path
-  | otherwise =
-      case normalise path of
-        -- note: as of filepath-1.4.1.0 normalise doesn't honor \\?\
-        -- https://github.com/haskell/filepath/issues/56
-        -- this means we cannot trust the result of normalise on
-        -- paths that start with \\?\
-        '\\' : '\\' : '?' : '\\' : _ -> path
-        '\\' : '\\' : '.' : '\\' : _ -> path
-        '\\' : subpath@('\\' : _) -> "\\\\?\\UNC" <> subpath
-        normalisedPath -> "\\\\?\\" <> normalisedPath
+win32_fILE_FLAG_OPEN_REPARSE_POINT :: Win32.FileAttributeOrFlag
+win32_fILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
 
+win32_fSCTL_GET_REPARSE_POINT :: Win32.DWORD
+win32_fSCTL_GET_REPARSE_POINT = 0x900a8
+
+win32_iO_REPARSE_TAG_MOUNT_POINT, win32_iO_REPARSE_TAG_SYMLINK :: CULong
+win32_iO_REPARSE_TAG_MOUNT_POINT = (#const IO_REPARSE_TAG_MOUNT_POINT)
+win32_iO_REPARSE_TAG_SYMLINK = (#const IO_REPARSE_TAG_SYMLINK)
+
+win32_mAXIMUM_REPARSE_DATA_BUFFER_SIZE :: Win32.DWORD
+win32_mAXIMUM_REPARSE_DATA_BUFFER_SIZE =
+  (#const MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
+
+win32_sYMLINK_FLAG_RELATIVE :: CULong
+win32_sYMLINK_FLAG_RELATIVE = 0x00000001
+
+data Win32_REPARSE_DATA_BUFFER
+  = Win32_MOUNT_POINT_REPARSE_DATA_BUFFER WindowsString WindowsString
+    -- ^ substituteName printName
+  | Win32_SYMLINK_REPARSE_DATA_BUFFER WindowsString WindowsString Bool
+    -- ^ substituteName printName isRelative
+  | Win32_GENERIC_REPARSE_DATA_BUFFER
+
+win32_alloca_REPARSE_DATA_BUFFER
+  :: ((Ptr Win32_REPARSE_DATA_BUFFER, Int) -> IO a) -> IO a
+win32_alloca_REPARSE_DATA_BUFFER action =
+  allocaBytesAligned size align $ \ ptr ->
+    action (ptr, size)
+  where size = fromIntegral win32_mAXIMUM_REPARSE_DATA_BUFFER_SIZE
+        align = #{alignment HsDirectory_REPARSE_DATA_BUFFER}
+
+win32_peek_REPARSE_DATA_BUFFER
+  :: Ptr Win32_REPARSE_DATA_BUFFER -> IO Win32_REPARSE_DATA_BUFFER
+win32_peek_REPARSE_DATA_BUFFER p = do
+  tag <- #{peek HsDirectory_REPARSE_DATA_BUFFER, ReparseTag} p
+  case () of
+    _ | tag == win32_iO_REPARSE_TAG_MOUNT_POINT -> do
+          let buf = #{ptr HsDirectory_REPARSE_DATA_BUFFER,
+                          MountPointReparseBuffer.PathBuffer} p
+          sni <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        MountPointReparseBuffer.SubstituteNameOffset} p
+          sns <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        MountPointReparseBuffer.SubstituteNameLength} p
+          sn <- peekName buf sni sns
+          pni <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        MountPointReparseBuffer.PrintNameOffset} p
+          pns <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        MountPointReparseBuffer.PrintNameLength} p
+          pn <- peekName buf pni pns
+          pure (Win32_MOUNT_POINT_REPARSE_DATA_BUFFER sn pn)
+      | tag == win32_iO_REPARSE_TAG_SYMLINK -> do
+          let buf = #{ptr HsDirectory_REPARSE_DATA_BUFFER,
+                          SymbolicLinkReparseBuffer.PathBuffer} p
+          sni <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        SymbolicLinkReparseBuffer.SubstituteNameOffset} p
+          sns <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        SymbolicLinkReparseBuffer.SubstituteNameLength} p
+          sn <- peekName buf sni sns
+          pni <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        SymbolicLinkReparseBuffer.PrintNameOffset} p
+          pns <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                        SymbolicLinkReparseBuffer.PrintNameLength} p
+          pn <- peekName buf pni pns
+          flags <- #{peek HsDirectory_REPARSE_DATA_BUFFER,
+                          SymbolicLinkReparseBuffer.Flags} p
+          pure (Win32_SYMLINK_REPARSE_DATA_BUFFER sn pn
+                (flags .&. win32_sYMLINK_FLAG_RELATIVE /= 0))
+      | otherwise -> pure Win32_GENERIC_REPARSE_DATA_BUFFER
+  where
+    peekName :: Ptr CWchar -> CUShort -> CUShort -> IO WindowsString
+    peekName buf offset size =
+      Win32.peekTStringLen ( buf `plusPtr` fromIntegral offset
+                           , fromIntegral size `div` sizeOf (0 :: CWchar) )
+
+deviceIoControl
+  :: Win32.HANDLE
+  -> Win32.DWORD
+  -> (Ptr a, Int)
+  -> (Ptr b, Int)
+  -> Maybe Void
+  -> IO (Either Win32.ErrCode Int)
+deviceIoControl h code (inPtr, inSize) (outPtr, outSize) _ = do
+  with 0 $ \ lenPtr -> do
+    ok <- c_DeviceIoControl h code inPtr (fromIntegral inSize) outPtr
+                            (fromIntegral outSize) lenPtr nullPtr
+    if ok
+      then Right . fromIntegral <$> peek lenPtr
+      else Left <$> Win32.getLastError
+
+foreign import WINAPI unsafe "windows.h DeviceIoControl"
+  c_DeviceIoControl
+    :: Win32.HANDLE
+    -> Win32.DWORD
+    -> Ptr a
+    -> Win32.DWORD
+    -> Ptr b
+    -> Win32.DWORD
+    -> Ptr Win32.DWORD
+    -> Ptr Void
+    -> IO Win32.BOOL
+
+readSymbolicLink :: OsPath -> IO OsPath
+readSymbolicLink path =
+  (`ioeSetOsPath` path) `modifyIOError` do
+    path' <- furnishPath path
+    let open = Win32.createFile path' 0 maxShareMode Nothing Win32.oPEN_EXISTING
+                                (Win32.fILE_FLAG_BACKUP_SEMANTICS .|.
+                                win32_fILE_FLAG_OPEN_REPARSE_POINT) Nothing
+    bracket open Win32.closeHandle $ \ h -> do
+      win32_alloca_REPARSE_DATA_BUFFER $ \ ptrAndSize@(ptr, _) -> do
+        result <- deviceIoControl h win32_fSCTL_GET_REPARSE_POINT
+                                  (nullPtr, 0) ptrAndSize Nothing
+        case result of
+          Left e | e == win32_eRROR_INVALID_FUNCTION -> do
+                     let msg = "Incorrect function. The file system " <>
+                               "might not support symbolic links."
+                     throwIO (mkIOError illegalOperationErrorType
+                                        "DeviceIoControl" Nothing Nothing
+                              `ioeSetErrorString` msg)
+                 | otherwise -> Win32.failWith "DeviceIoControl" e
+          Right _ -> pure ()
+        rData <- win32_peek_REPARSE_DATA_BUFFER ptr
+        strip . OsString <$> case rData of
+          Win32_MOUNT_POINT_REPARSE_DATA_BUFFER sn _ -> pure sn
+          Win32_SYMLINK_REPARSE_DATA_BUFFER sn _ _ -> pure sn
+          _ -> throwIO (mkIOError InappropriateType
+                                  "readSymbolicLink" Nothing Nothing)
+  where
+    strip sn =
+      fromMaybe sn
+        (pack <$> List.stripPrefix (unpack (os "\\??\\")) (unpack sn))
+
+-- | On Windows, equivalent to 'simplifyWindows'.
+simplify :: OsPath -> OsPath
+simplify = simplifyWindows
+
+-- | Normalise the path separators and prepend the @"\\\\?\\"@ prefix if
+-- necessary or possible.  This is used for symbolic links targets because
+-- they can't handle forward slashes.
+normaliseSeparators :: OsPath -> WindowsPath
+normaliseSeparators path
+  | isRelative path = getOsString (pack (normaliseSep <$> unpack path))
+  | otherwise = toExtendedLengthPath path
+  where normaliseSep c = if isPathSeparator c then pathSeparator else c
+
+-- | 'simplify' the path and prepend the @"\\\\?\\"@ if possible.  This
+-- function can sometimes be used to bypass the @MAX_PATH@ length restriction
+-- in Windows API calls.
+toExtendedLengthPath :: OsPath -> WindowsPath
+toExtendedLengthPath path =
+  getOsString $
+  if isRelative path
+  then simplifiedPath
+  else
+    case toChar <$> simplifiedPath' of
+      '\\' : '?'  : '?' : '\\' : _ -> simplifiedPath
+      '\\' : '\\' : _ -> simplifiedPath
+      _ -> os "\\\\?\\" <> simplifiedPath
+  where simplifiedPath = simplify path
+        simplifiedPath' = unpack simplifiedPath
+
+-- | Make a path absolute and convert to an extended length path, if possible.
+--
+-- Empty paths are left unchanged.
+--
+-- This function never fails.  If it doesn't understand the path, it just
+-- returns the path unchanged.
+furnishPath :: OsPath -> IO WindowsPath
+furnishPath path =
+  (toExtendedLengthPath <$> rawPrependCurrentDirectory path)
+    `catchIOError` \ _ ->
+      pure (getOsString path)
+
 -- | Strip the @"\\\\?\\"@ prefix if possible.
 -- The prefix is kept if the meaning of the path would otherwise change.
-fromExtendedLengthPath :: FilePath -> FilePath
-fromExtendedLengthPath ePath =
-  case ePath of
-    '\\' : '\\' : '?' : '\\' : path ->
+fromExtendedLengthPath :: WindowsPath -> OsPath
+fromExtendedLengthPath ePath' =
+  case unpack ePath of
+    c1 : c2 : c3 : c4 : path
+      | (toChar <$> [c1, c2, c3, c4]) == "\\\\?\\" ->
       case path of
-        'U' : 'N' : 'C' : subpath@('\\' : _) -> "\\" <> subpath
-        drive : ':' : subpath
+        c5 : c6 : c7 : subpath@(c8 : _)
+          | (toChar <$> [c5, c6, c7, c8]) == "UNC\\" ->
+            pack (c8 : subpath)
+        drive : col : subpath
           -- if the path is not "regular", then the prefix is necessary
           -- to ensure the path is interpreted literally
-          | isAlpha drive && isAscii drive && isPathRegular subpath -> path
+          | toChar col == ':', isDriveChar drive, isPathRegular subpath ->
+            pack path
         _ -> ePath
     _ -> ePath
   where
+    ePath = OsString ePath'
+    isDriveChar drive = isAlpha (toChar drive) && isAscii (toChar drive)
     isPathRegular path =
-      not ('/' `elem` path ||
-           "." `elem` splitDirectories path ||
-           ".." `elem` splitDirectories path)
+      not ('/' `elem` (toChar <$> path) ||
+           os "." `elem` splitDirectories (pack path) ||
+           os ".." `elem` splitDirectories (pack path))
 
-getPathNameWith :: (Ptr CWchar -> Win32.DWORD -> IO Win32.DWORD) -> IO FilePath
-getPathNameWith cFunc = do
-  let getPathNameWithLen len = do
-        allocaArray (fromIntegral len) $ \ ptrPathOut -> do
-          len' <- Win32.failIfZero "" (cFunc ptrPathOut len)
-          if len' <= len
-            then Right <$> peekCWStringLen (ptrPathOut, fromIntegral len')
-            else pure (Left len')
-  r <- getPathNameWithLen ((#const MAX_PATH) * (#size wchar_t))
-  case r of
-    Right s -> pure s
-    Left len -> do
-      r' <- getPathNameWithLen len
-      case r' of
-        Right s -> pure s
-        Left _ -> ioError (mkIOError OtherError "" Nothing Nothing
-                           `ioeSetErrorString` "path changed unexpectedly")
+saturatingDouble :: Win32.DWORD -> Win32.DWORD
+saturatingDouble s | s > maxBound `div` 2 = maxBound
+                   | otherwise            = s * 2
 
-foreign import ccall unsafe "_wchmod"
-  c_wchmod :: CWString -> CMode -> IO CInt
+-- Handles Windows APIs that write strings through a user-provided buffer and
+-- can propose a new length when it isn't big enough. This is similar to
+-- Win32.try, but also returns the precise error code.
+peekTStringWith :: Win32.DWORD
+                -> (Win32.LPTSTR -> Win32.DWORD -> IO Win32.DWORD)
+                -- ^ Must accept a buffer and its size in TCHARs. If the
+                --   buffer is large enough for the function, it must write a
+                --   string to it, which need not be null-terminated, and
+                --   return the length of the string, not including the null
+                --   terminator if present. If the buffer is too small, it
+                --   must return a proposed buffer size in TCHARs, although it
+                --   need not guarantee success with the proposed size if,
+                --   say, the underlying data changes in the interim. If it
+                --   fails for any other reason, it must return zero and
+                --   communicate the error code through GetLastError.
+                -> IO (Either Win32.ErrCode WindowsPath)
+peekTStringWith bufferSize cFunc = do
+  outcome <- do
+    allocaArray (fromIntegral bufferSize) $ \ ptr -> do
+      size <- cFunc ptr bufferSize
+      case size of
+        0 -> Right . Left <$> Win32.getLastError
+        _ | size <= bufferSize ->
+              Right . Right <$> Win32.peekTStringLen (ptr, fromIntegral size)
+          | otherwise ->
+              -- At least double the size to ensure fast termination.
+              pure (Left (max size (saturatingDouble bufferSize)))
+  case outcome of
+    Left proposedSize -> peekTStringWith proposedSize cFunc
+    Right result      -> pure result
 
-s_IRUSR :: CMode
-s_IRUSR = (#const S_IRUSR)
+realPath :: OsPath -> IO OsPath
+realPath = getFinalPathName
 
-s_IWUSR :: CMode
-s_IWUSR = (#const S_IWUSR)
+canonicalizePathSimplify :: OsPath -> IO OsPath
+canonicalizePathSimplify path =
+  getFullPathName path
+    `catchIOError` \ _ ->
+      pure path
 
-s_IXUSR :: CMode
-s_IXUSR = (#const S_IXUSR)
+searchPathEnvForExes :: OsString -> IO (Maybe OsPath)
+searchPathEnvForExes binaryPath@(OsString binary) = do
+  maybePath <- search
+    `catch` \e ->
+      if ioeGetErrorType e == InvalidArgument
+      then pure Nothing
+      else throwIO e
+  pure (OsString <$> maybePath >>= verify)
+ where
+  search = Win32.searchPath Nothing binary (Just (getOsString exeExtension))
+  verify p
+    | hasExtension binaryPath || exeExtension `isExtensionOf` p = Just p
+    | otherwise = Nothing
 
-s_IFDIR :: CMode
-s_IFDIR = (#const S_IFDIR)
+findExecutablesLazyInternal :: ([OsPath] -> OsString -> ListT IO OsPath)
+                            -> OsString
+                            -> ListT IO OsPath
+findExecutablesLazyInternal _ = maybeToListT . searchPathEnvForExes
+
+exeExtensionInternal :: OsString
+exeExtensionInternal = exeExtension
+
+readDirToEnd :: RawHandle -> IO [OsPath]
+readDirToEnd = getDirectoryContentsInternal
+
+getDirectoryContentsInternal :: OsPath -> IO [OsPath]
+getDirectoryContentsInternal path = do
+  query <- furnishPath (path </> os "*")
+  bracket
+    (Win32.findFirstFile query)
+    (\ (h, _) -> Win32.findClose h)
+    (\ (h, fdat) -> loop h fdat [])
+  where
+    -- we needn't worry about empty directories: a directory always
+    -- has at least "." and ".." entries
+    loop :: Win32.HANDLE -> Win32.FindData -> [OsPath] -> IO [OsPath]
+    loop h fdat acc = do
+      filename <- Win32.getFindDataFileName fdat
+      more <- Win32.findNextFile h fdat
+      if more
+        then loop h fdat (OsString filename : acc)
+        else pure (OsString filename : acc)
+             -- no need to reverse, ordering is undefined
+
+getCurrentDirectoryInternal :: IO OsPath
+getCurrentDirectoryInternal = OsString <$> Win32.getCurrentDirectory
+
+getFullPathName :: OsPath -> IO OsPath
+getFullPathName path =
+  fromExtendedLengthPath <$> Win32.getFullPathName (toExtendedLengthPath path)
+
+-- | Similar to 'prependCurrentDirectory' but fails for empty paths.
+rawPrependCurrentDirectory :: OsPath -> IO OsPath
+rawPrependCurrentDirectory path
+  | isRelative path =
+    ((`ioeAddLocation` "prependCurrentDirectory") .
+     (`ioeSetOsPath` path)) `modifyIOError` do
+      getFullPathName path
+  | otherwise = pure path
+
+-- | Convert a path into an absolute path.  If the given path is relative, the
+-- current directory is prepended and the path may or may not be simplified.
+-- If the path is already absolute, the path is returned unchanged.  The
+-- function preserves the presence or absence of the trailing path separator.
+--
+-- If the path is already absolute, the operation never fails.  Otherwise, the
+-- operation may throw exceptions.
+--
+-- Empty paths are treated as the current directory.
+prependCurrentDirectory :: OsPath -> IO OsPath
+prependCurrentDirectory = rawPrependCurrentDirectory . emptyToCurDir
+
+-- SetCurrentDirectory does not support long paths even with the \\?\ prefix
+-- https://ghc.haskell.org/trac/ghc/ticket/13373#comment:6
+setCurrentDirectoryInternal :: OsPath -> IO ()
+setCurrentDirectoryInternal = Win32.setCurrentDirectory . getOsString
+
+createSymbolicLinkUnpriv :: WindowsPath -> WindowsPath -> Bool -> IO ()
+createSymbolicLinkUnpriv link _target _isDir =
+#ifdef HAVE_CREATESYMBOLICLINKW
+  Win32.withTString link $ \ pLink ->
+  Win32.withTString _target $ \ pTarget -> do
+    let flags = if _isDir then win32_sYMBOLIC_LINK_FLAG_DIRECTORY else 0
+    call pLink pTarget flags win32_sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+  where
+    call pLink pTarget flags unpriv = do
+      status <- c_CreateSymbolicLink pLink pTarget (flags .|. unpriv)
+      when (status == 0) $ do
+        e <- Win32.getLastError
+        case () of
+          _ | e == win32_eRROR_INVALID_FUNCTION -> do
+                let msg = "Incorrect function. The underlying file system " <>
+                          "might not support symbolic links."
+                throwIO (mkIOError illegalOperationErrorType
+                                   "CreateSymbolicLink" Nothing Nothing
+                         `ioeSetOsPath` OsString link
+                         `ioeSetErrorString` msg)
+            | e == win32_eRROR_PRIVILEGE_NOT_HELD -> do
+                let msg = "A required privilege is not held by the client. " <>
+                          "Creating symbolic links usually requires " <>
+                          "administrative rights."
+                throwIO (mkIOError permissionErrorType "CreateSymbolicLink"
+                                   Nothing Nothing
+                         `ioeSetOsPath` OsString link
+                         `ioeSetErrorString` msg)
+            | e == win32_eRROR_INVALID_PARAMETER &&
+              unpriv /= 0 ->
+                -- for compatibility with older versions of Windows,
+                -- try it again without the flag
+                call pLink pTarget flags 0
+            | otherwise -> Win32.failWith "CreateSymbolicLink" e
+
+foreign import WINAPI unsafe "windows.h CreateSymbolicLinkW"
+  c_CreateSymbolicLink
+    :: Ptr CWchar -> Ptr CWchar -> Win32.DWORD -> IO Win32.BYTE
+
+#else
+  throwIO . (`ioeSetErrorString` unsupportedErrorMsg)
+          . (`ioeSetOsPath` OsString link) $
+               mkIOError UnsupportedOperation "CreateSymbolicLink"
+                         Nothing Nothing
+  where unsupportedErrorMsg = "Not supported on Windows XP or older"
+#endif
+
+linkToDirectoryIsDirectory :: Bool
+linkToDirectoryIsDirectory = True
+
+createSymbolicLink :: Bool -> OsPath -> OsPath -> IO ()
+createSymbolicLink isDir target link =
+  (`ioeSetOsPath` link) `modifyIOError` do
+    -- normaliseSeparators ensures the target gets normalised properly
+    link' <- furnishPath link
+    createSymbolicLinkUnpriv
+      link'
+      (normaliseSeparators target)
+      isDir
+
+type Metadata = Win32.BY_HANDLE_FILE_INFORMATION
+
+getMetadataAt :: WhetherFollow -> Maybe RawHandle -> OsPath -> IO Metadata
+getMetadataAt NoFollow    dir path = getSymbolicLinkMetadata (pathAt dir path)
+getMetadataAt FollowLinks dir path = getFileMetadata         (pathAt dir path)
+
+getSymbolicLinkMetadata :: OsPath -> IO Metadata
+getSymbolicLinkMetadata path =
+  (`ioeSetOsPath` path) `modifyIOError` do
+    path' <- furnishPath path
+    let open = Win32.createFile path' 0 maxShareMode Nothing Win32.oPEN_EXISTING
+                                (Win32.fILE_FLAG_BACKUP_SEMANTICS .|.
+                                 win32_fILE_FLAG_OPEN_REPARSE_POINT) Nothing
+    bracket open Win32.closeHandle $ \ h -> do
+      Win32.getFileInformationByHandle h
+
+getFileMetadata :: OsPath -> IO Metadata
+getFileMetadata path =
+  (`ioeSetOsPath` path) `modifyIOError` do
+    path' <- furnishPath path
+    let open = Win32.createFile path' 0 maxShareMode Nothing Win32.oPEN_EXISTING
+                                Win32.fILE_FLAG_BACKUP_SEMANTICS Nothing
+    bracket open Win32.closeHandle $ \ h -> do
+      Win32.getFileInformationByHandle h
+
+fileTypeFromMetadata :: Metadata -> FileType
+fileTypeFromMetadata info
+  | isLink    = if isDir then DirectoryLink else SymbolicLink
+  | isDir     = Directory
+  | otherwise = File
+  where
+    isLink = attrs .&. Win32.fILE_ATTRIBUTE_REPARSE_POINT /= 0
+    isDir  = attrs .&. Win32.fILE_ATTRIBUTE_DIRECTORY /= 0
+    attrs  = Win32.bhfiFileAttributes info
+
+fileSizeFromMetadata :: Metadata -> Integer
+fileSizeFromMetadata = fromIntegral . Win32.bhfiSize
+
+accessTimeFromMetadata :: Metadata -> UTCTime
+accessTimeFromMetadata =
+  posixSecondsToUTCTime . windowsToPosixTime . Win32.bhfiLastAccessTime
+
+modificationTimeFromMetadata :: Metadata -> UTCTime
+modificationTimeFromMetadata =
+  posixSecondsToUTCTime . windowsToPosixTime . Win32.bhfiLastWriteTime
+
+-- | Difference between the Windows and POSIX epochs in units of 100ns.
+windowsPosixEpochDifference :: Num a => a
+windowsPosixEpochDifference = 116444736000000000
+
+-- | Convert from Windows time to POSIX time.
+windowsToPosixTime :: Win32.FILETIME -> POSIXTime
+windowsToPosixTime (Win32.FILETIME t) =
+  (fromIntegral t - windowsPosixEpochDifference) / 10000000
+
+-- | Convert from POSIX time to Windows time.  This is lossy as Windows time
+--   has a resolution of only 100ns.
+posixToWindowsTime :: POSIXTime -> Win32.FILETIME
+posixToWindowsTime t = Win32.FILETIME $
+  truncate (t * 10000000 + windowsPosixEpochDifference)
+
+setTimes :: OsPath -> (Maybe POSIXTime, Maybe POSIXTime) -> IO ()
+setTimes path' (atime', mtime') =
+  bracket (openFileHandle path' Win32.gENERIC_WRITE)
+          Win32.closeHandle $ \ handle ->
+  Win32.setFileTime
+    handle
+    Nothing
+    (posixToWindowsTime <$> atime')
+    (posixToWindowsTime <$> mtime')
+
+-- | Open the handle of an existing file or directory.
+openFileHandle :: OsString -> Win32.AccessMode -> IO Win32.HANDLE
+openFileHandle path mode =
+  (`ioeSetOsPath` path) `modifyIOError` do
+    path' <- furnishPath path
+    Win32.createFile path' mode maxShareMode Nothing
+                     Win32.oPEN_EXISTING flags Nothing
+  where flags =  Win32.fILE_ATTRIBUTE_NORMAL
+             .|. Win32.fILE_FLAG_BACKUP_SEMANTICS -- required for directories
+
+type Mode = Win32.FileAttributeOrFlag
+
+modeFromMetadata :: Metadata -> Mode
+modeFromMetadata = Win32.bhfiFileAttributes
+
+hasWriteMode :: Mode -> Bool
+hasWriteMode m = m .&. Win32.fILE_ATTRIBUTE_READONLY == 0
+
+setWriteMode :: Bool -> Mode -> Mode
+setWriteMode False m = m .|. Win32.fILE_ATTRIBUTE_READONLY
+setWriteMode True  m = m .&. complement Win32.fILE_ATTRIBUTE_READONLY
+
+setForceRemoveMode :: Mode -> Mode
+setForceRemoveMode m = m .&. complement Win32.fILE_ATTRIBUTE_READONLY
+
+setModeAt :: Maybe RawHandle -> OsPath -> Mode -> IO ()
+setModeAt dir path = setFileMode (pathAt dir path)
+
+setFileMode :: OsPath -> Mode -> IO ()
+setFileMode path mode =
+  (`ioeSetOsPath` path) `modifyIOError` do
+    path' <- furnishPath path
+    Win32.setFileAttributes path' mode
+
+-- | A restricted form of 'setFileMode' that only sets the permission bits.
+-- For Windows, this means only the "read-only" attribute is affected.
+setFilePermissions :: OsPath -> Mode -> IO ()
+setFilePermissions path m = do
+  m' <- modeFromMetadata <$> getFileMetadata path
+  setFileMode path ((m' .&. complement Win32.fILE_ATTRIBUTE_READONLY) .|.
+                    (m  .&. Win32.fILE_ATTRIBUTE_READONLY))
+
+getAccessPermissions :: OsPath -> IO Permissions
+getAccessPermissions path = do
+  m <- getFileMetadata path
+  let isDir = fileTypeIsDirectory (fileTypeFromMetadata m)
+  let w = hasWriteMode (modeFromMetadata m)
+  let x = (toLower . toChar <$> unpack (takeExtension path))
+          `elem` [".bat", ".cmd", ".com", ".exe"]
+  pure Permissions
+       { readable   = True
+       , writable   = w
+       , executable = x && not isDir
+       , searchable = isDir
+       }
+
+setAccessPermissions :: OsPath -> Permissions -> IO ()
+setAccessPermissions path Permissions{writable = w} = do
+  setFilePermissions path (setWriteMode w 0)
+
+getFolderPath :: Win32.CSIDL -> IO OsPath
+getFolderPath what = OsString <$> Win32.sHGetFolderPath nullPtr what nullPtr 0
+
+getHomeDirectoryInternal :: IO OsPath
+getHomeDirectoryInternal =
+  getFolderPath Win32.cSIDL_PROFILE `catchIOError` \ _ ->
+    getFolderPath Win32.cSIDL_WINDOWS
+
+getXdgDirectoryFallback :: IO OsPath -> XdgDirectory -> IO OsPath
+getXdgDirectoryFallback _ xdgDir = do
+  case xdgDir of
+    XdgData   -> getFolderPath Win32.cSIDL_APPDATA
+    XdgConfig -> getFolderPath Win32.cSIDL_APPDATA
+    XdgCache  -> getFolderPath Win32.cSIDL_LOCAL_APPDATA
+    XdgState  -> getFolderPath Win32.cSIDL_LOCAL_APPDATA
+
+getXdgDirectoryListFallback :: XdgDirectoryList -> IO [OsPath]
+getXdgDirectoryListFallback _ =
+  pure <$> getFolderPath win32_cSIDL_COMMON_APPDATA
+
+getAppUserDataDirectoryInternal :: OsPath -> IO OsPath
+getAppUserDataDirectoryInternal appName =
+  (\ appData -> appData <> (os "\\" <> appName))
+  <$> getXdgDirectoryFallback getHomeDirectoryInternal XdgData
+
+getUserDocumentsDirectoryInternal :: IO OsPath
+getUserDocumentsDirectoryInternal = getFolderPath Win32.cSIDL_PERSONAL
+
+getTemporaryDirectoryInternal :: IO OsPath
+getTemporaryDirectoryInternal = OsString <$> Win32.getTemporaryDirectory
 
 #endif
diff --git a/System/Directory/Internal/utility.h b/System/Directory/Internal/utility.h
deleted file mode 100644
--- a/System/Directory/Internal/utility.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#if !defined alignof && __cplusplus < 201103L
-# ifdef STDC_HEADERS
-#  include <stddef.h>
-# endif
-# define alignof(x) offsetof(struct { char c; x m; }, m)
-#endif
diff --git a/System/Directory/Internal/windows_ext.h b/System/Directory/Internal/windows_ext.h
new file mode 100644
--- /dev/null
+++ b/System/Directory/Internal/windows_ext.h
@@ -0,0 +1,33 @@
+#ifndef HS_DIRECTORY_WINDOWS_EXT_H
+#define HS_DIRECTORY_WINDOWS_EXT_H
+#include <windows.h>
+
+// define prototype to get size, offsets, and alignments
+// (can't include <ntifs.h> because that only exists in WDK)
+typedef struct {
+    ULONG ReparseTag;
+    USHORT ReparseDataLength;
+    USHORT Reserved;
+    union {
+        struct {
+            USHORT SubstituteNameOffset;
+            USHORT SubstituteNameLength;
+            USHORT PrintNameOffset;
+            USHORT PrintNameLength;
+            ULONG Flags;
+            WCHAR PathBuffer[1];
+        } SymbolicLinkReparseBuffer;
+        struct {
+            USHORT SubstituteNameOffset;
+            USHORT SubstituteNameLength;
+            USHORT PrintNameOffset;
+            USHORT PrintNameLength;
+            WCHAR PathBuffer[1];
+        } MountPointReparseBuffer;
+        struct {
+            UCHAR DataBuffer[1];
+        } GenericReparseBuffer;
+    };
+} HsDirectory_REPARSE_DATA_BUFFER;
+
+#endif
diff --git a/System/Directory/OsPath.hs b/System/Directory/OsPath.hs
new file mode 100644
--- /dev/null
+++ b/System/Directory/OsPath.hs
@@ -0,0 +1,1669 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  System.Directory.OsPath
+-- Copyright   :  (c) The University of Glasgow 2001
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- System-independent interface to directory manipulation.
+--
+-- @since 1.3.8.0
+--
+-----------------------------------------------------------------------------
+
+module System.Directory.OsPath
+   (
+    -- $intro
+
+    -- * Actions on directories
+      createDirectory
+    , createDirectoryIfMissing
+    , removeDirectory
+    , removeDirectoryRecursive
+    , removePathForcibly
+    , renameDirectory
+    , listDirectory
+    , getDirectoryContents
+    -- ** Current working directory
+    , getCurrentDirectory
+    , setCurrentDirectory
+    , withCurrentDirectory
+
+    -- * Pre-defined directories
+    , getHomeDirectory
+    , XdgDirectory(..)
+    , getXdgDirectory
+    , XdgDirectoryList(..)
+    , getXdgDirectoryList
+    , getAppUserDataDirectory
+    , getUserDocumentsDirectory
+    , getTemporaryDirectory
+
+    -- * PATH
+    , getExecSearchPath
+
+    -- * Actions on files
+    , removeFile
+    , renameFile
+    , renamePath
+    , copyFile
+    , copyFileWithMetadata
+    , getFileSize
+
+    , canonicalizePath
+    , makeAbsolute
+    , makeRelativeToCurrentDirectory
+
+    -- * Existence tests
+    , doesPathExist
+    , doesFileExist
+    , doesDirectoryExist
+
+    , findExecutable
+    , findExecutables
+    , findExecutablesInDirectories
+    , findFile
+    , findFiles
+    , findFileWith
+    , findFilesWith
+    , exeExtension
+
+    -- * Symbolic links
+    , createFileLink
+    , createDirectoryLink
+    , removeDirectoryLink
+    , pathIsSymbolicLink
+    , getSymbolicLinkTarget
+
+    -- * Permissions
+
+    -- $permissions
+
+    , Permissions
+    , emptyPermissions
+    , readable
+    , writable
+    , executable
+    , searchable
+    , setOwnerReadable
+    , setOwnerWritable
+    , setOwnerExecutable
+    , setOwnerSearchable
+
+    , getPermissions
+    , setPermissions
+    , copyPermissions
+
+    -- * Timestamps
+
+    , getAccessTime
+    , getModificationTime
+    , setAccessTime
+    , setModificationTime
+
+   ) where
+import Prelude ()
+import System.Directory.Internal
+import System.Directory.Internal.Prelude
+import System.OsPath
+  ( (<.>)
+  , (</>)
+  , addTrailingPathSeparator
+  , dropTrailingPathSeparator
+  , hasTrailingPathSeparator
+  , isAbsolute
+  , joinPath
+  , makeRelative
+  , splitDirectories
+  , splitSearchPath
+  , takeDirectory
+  , encodeWith
+  )
+import qualified Data.List.NonEmpty as NE
+import Data.Time (UTCTime)
+import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds)
+import GHC.IO.Encoding.UTF8 ( mkUTF8 )
+import GHC.IO.Encoding.UTF16 ( mkUTF16le )
+import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )
+
+{- $intro
+A directory contains a series of entries, each of which is a named
+reference to a file system object (file, directory etc.).  Some
+entries may be hidden, inaccessible, or have some administrative
+function (e.g. @.@ or @..@ under
+<http://www.opengroup.org/onlinepubs/009695399 POSIX>), but in
+this standard all such entries are considered to form part of the
+directory contents. Entries in sub-directories are not, however,
+considered to form part of the directory contents.
+
+Each file system object is referenced by a /path/.  There is
+normally at least one absolute path to each file system object.  In
+some operating systems, it may also be possible to have paths which
+are relative to the current directory.
+
+Unless otherwise documented:
+
+* 'IO' operations in this package may throw any 'IOError'.  No other types of
+  exceptions shall be thrown.
+
+* The list of possible 'IOErrorType's in the API documentation is not
+  exhaustive.  The full list may vary by platform and/or evolve over time.
+
+-}
+
+-----------------------------------------------------------------------------
+-- Permissions
+
+{- $permissions
+
+directory offers a limited (and quirky) interface for reading and setting file
+and directory permissions; see 'getPermissions' and 'setPermissions' for a
+discussion of their limitations.  Because permissions are very difficult to
+implement portably across different platforms, users who wish to do more
+sophisticated things with permissions are advised to use other,
+platform-specific libraries instead.  For example, if you are only interested
+in permissions on POSIX-like platforms,
+<https://hackage.haskell.org/package/unix/docs/System-Posix-Files.html unix>
+offers much more flexibility.
+
+ The 'Permissions' type is used to record whether certain operations are
+ permissible on a file\/directory. 'getPermissions' and 'setPermissions'
+ get and set these permissions, respectively. Permissions apply both to
+ files and directories. For directories, the executable field will be
+ 'False', and for files the searchable field will be 'False'. Note that
+ directories may be searchable without being readable, if permission has
+ been given to use them as part of a path, but not to examine the
+ directory contents.
+
+Note that to change some, but not all permissions, a construct on the
+following lines must be used.
+
+>  makeReadable f = do
+>     p <- getPermissions f
+>     setPermissions f (p {readable = True})
+
+-}
+
+emptyPermissions :: Permissions
+emptyPermissions = Permissions {
+                       readable   = False,
+                       writable   = False,
+                       executable = False,
+                       searchable = False
+                   }
+
+setOwnerReadable :: Bool -> Permissions -> Permissions
+setOwnerReadable b p = p { readable = b }
+
+setOwnerWritable :: Bool -> Permissions -> Permissions
+setOwnerWritable b p = p { writable = b }
+
+setOwnerExecutable :: Bool -> Permissions -> Permissions
+setOwnerExecutable b p = p { executable = b }
+
+setOwnerSearchable :: Bool -> Permissions -> Permissions
+setOwnerSearchable b p = p { searchable = b }
+
+-- | Get the permissions of a file or directory.
+--
+-- On Windows, the 'writable' permission corresponds to the "read-only"
+-- attribute.  The 'executable' permission is set if the file extension is of
+-- an executable file type.  The 'readable' permission is always set.
+--
+-- On POSIX systems, this returns the result of @access@.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to access the
+--   permissions, or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+getPermissions :: OsPath -> IO Permissions
+getPermissions path =
+  (`ioeAddLocation` "getPermissions") `modifyIOError` do
+    getAccessPermissions (emptyToCurDir path)
+
+-- | Set the permissions of a file or directory.
+--
+-- On Windows, this is only capable of changing the 'writable' permission,
+-- which corresponds to the "read-only" attribute.  Changing the other
+-- permissions has no effect.
+--
+-- On POSIX systems, this sets the /owner/ permissions.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to set the permissions,
+--   or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+setPermissions :: OsPath -> Permissions -> IO ()
+setPermissions path p =
+  (`ioeAddLocation` "setPermissions") `modifyIOError` do
+    setAccessPermissions (emptyToCurDir path) p
+
+-- | Copy the permissions of one file to another.  This reproduces the
+-- permissions more accurately than using 'getPermissions' followed by
+-- 'setPermissions'.
+--
+-- On Windows, this copies only the read-only attribute.
+--
+-- On POSIX systems, this is equivalent to @stat@ followed by @chmod@.
+copyPermissions :: OsPath -> OsPath -> IO ()
+copyPermissions src dst =
+  (`ioeAddLocation` "copyPermissions") `modifyIOError` do
+    m <- getFileMetadata src
+    copyPermissionsFromMetadata m dst
+
+copyPermissionsFromMetadata :: Metadata -> OsPath -> IO ()
+copyPermissionsFromMetadata m dst = do
+  -- instead of setFileMode, setFilePermissions is used here
+  -- this is to retain backward compatibility in copyPermissions
+  setFilePermissions dst (modeFromMetadata m)
+
+-----------------------------------------------------------------------------
+-- Implementation
+
+{- |@'createDirectory' dir@ creates a new directory @dir@ which is
+initially empty, or as near to empty as the operating system
+allows.
+
+The operation may fail with:
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES]@
+
+* 'isAlreadyExistsError'
+The operand refers to a directory that already exists.
+@ [EEXIST]@
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+The operand is not a valid directory name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+There is no path to the directory.
+@[ENOENT, ENOTDIR]@
+
+* 'System.IO.isFullError'
+Insufficient resources (virtual memory, process file descriptors,
+physical disk space, etc.) are available to perform the operation.
+@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+
+* @InappropriateType@
+The path refers to an existing non-directory object.
+@[EEXIST]@
+
+-}
+
+createDirectory :: OsPath -> IO ()
+createDirectory = createDirectoryInternal
+
+-- | @'createDirectoryIfMissing' parents dir@ creates a new directory
+-- @dir@ if it doesn\'t exist. If the first argument is 'True'
+-- the function will also create all parent directories if they are missing.
+createDirectoryIfMissing
+  :: Bool   -- ^ Create its parents too?
+  -> OsPath -- ^ The path to the directory you want to make
+  -> IO ()
+createDirectoryIfMissing create_parents path0
+  | create_parents = createDirs (parents path0)
+  | otherwise      = createDirs (take 1 (parents path0))
+  where
+    parents = reverse . scanl1 (</>) . splitDirectories . simplify
+
+    createDirs []         = pure ()
+    createDirs [dir]      = createDir dir ioError
+    createDirs (dir:dirs) =
+      createDir dir $ \_ -> do
+        createDirs dirs
+        createDir dir ioError
+
+    createDir dir notExistHandler = do
+      r <- tryIOError (createDirectory dir)
+      case r of
+        Right ()                   -> pure ()
+        Left  e
+          | isDoesNotExistError  e -> notExistHandler e
+          -- createDirectory (and indeed POSIX mkdir) does not distinguish
+          -- between a dir already existing and a file already existing. So we
+          -- check for it here. Unfortunately there is a slight race condition
+          -- here, but we think it is benign. It could report an exception in
+          -- the case that the dir did exist but another process deletes the
+          -- directory and creates a file in its place before we can check
+          -- that the directory did indeed exist.
+          -- We also follow this path when we get a permissions error, as
+          -- trying to create "." when in the root directory on Windows
+          -- fails with
+          --     CreateDirectory ".": permission denied (Access is denied.)
+          -- This caused GHCi to crash when loading a module in the root
+          -- directory.
+          | isAlreadyExistsError e
+         || isPermissionError    e -> do
+              canIgnore <- pathIsDirectory dir
+                             `catchIOError` \ _ ->
+                               pure (isAlreadyExistsError e)
+              unless canIgnore (ioError e)
+          | otherwise              -> ioError e
+
+
+{- | @'removeDirectory' dir@ removes an existing directory /dir/.  The
+implementation may specify additional constraints which must be
+satisfied before a directory can be removed (e.g. the directory has to
+be empty, or may not be in use by other processes).  It is not legal
+for an implementation to partially remove a directory unless the
+entire directory is removed. A conformant implementation need not
+support directory removal in all situations (e.g. removal of the root
+directory).
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+The operand is not a valid directory name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The directory does not exist.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY, ENOTEMPTY, EEXIST]@
+
+* @UnsupportedOperation@
+The implementation does not support removal in this situation.
+@[EINVAL]@
+
+* @InappropriateType@
+The operand refers to an existing non-directory object.
+@[ENOTDIR]@
+
+-}
+
+removeDirectory :: OsPath -> IO ()
+removeDirectory = removePathInternal True
+
+type Preremover = Maybe RawHandle -> OsPath -> Metadata -> IO ()
+
+noPreremover :: Preremover
+noPreremover _ _ _ = pure ()
+
+forcePreremover :: Preremover
+forcePreremover dir path metadata = do
+  when (fileTypeIsDirectory (fileTypeFromMetadata metadata)
+        || not filesAlwaysRemovable) $ do
+    setModeAt dir path mode
+      `catchIOError` \ _ -> pure ()
+  where
+    mode = setForceRemoveMode (modeFromMetadata metadata)
+
+removeRecursivelyAt
+  :: (IO () -> IO ())
+  -> ([IO ()] -> IO ())
+  -> Preremover
+  -> Maybe RawHandle
+  -> OsPath
+  -> IO ()
+removeRecursivelyAt catcher sequencer preremover dir name = catcher $ do
+  metadata <- getMetadataAt NoFollow dir name
+  preremover dir name metadata
+  let
+    fileType = fileTypeFromMetadata metadata
+    subremovals = do
+      when (fileType == Directory) $ do
+        bracket (openRaw NoFollow dir name) closeRaw $ \ handle -> do
+          -- dropSpecialDotDirs is extremely important! Otherwise it will
+          -- recurse into the parent directory and wreak havoc.
+          names <- dropSpecialDotDirs <$> readDirToEnd handle
+          sequencer (recurse (Just handle) <$> names)
+  sequencer [subremovals, removePathAt fileType dir name]
+  where recurse = removeRecursivelyAt catcher sequencer preremover
+
+-- | @'removeDirectoryRecursive' dir@ removes an existing directory /dir/
+-- together with its contents and subdirectories. Within this directory,
+-- symbolic links are removed without affecting their targets.
+--
+-- On Windows, the operation fails if /dir/ is a directory symbolic link.
+--
+-- This operation is reported to be flaky on Windows so retry logic may
+-- be advisable. See: https://github.com/haskell/directory/pull/108
+removeDirectoryRecursive :: OsPath -> IO ()
+removeDirectoryRecursive path =
+  (`ioeAddLocation` "removeDirectoryRecursive") `modifyIOError` do
+    m <- getSymbolicLinkMetadata path
+    case fileTypeFromMetadata m of
+      Directory ->
+        removeRecursivelyAt id sequenceA_ noPreremover Nothing path
+      DirectoryLink ->
+        ioError (err `ioeSetErrorString` "is a directory symbolic link")
+      _ ->
+        ioError (err `ioeSetErrorString` "not a directory")
+  where err = mkIOError InappropriateType "" Nothing Nothing `ioeSetOsPath` path
+
+-- | Removes a file or directory at /path/ together with its contents and
+-- subdirectories. Symbolic links are removed without affecting their
+-- targets. If the path does not exist, nothing happens.
+--
+-- Unlike other removal functions, this function will also attempt to delete
+-- files marked as read-only or otherwise made unremovable due to permissions.
+-- As a result, if the removal is incomplete, the permissions or attributes on
+-- the remaining files may be altered.  If there are hard links in the
+-- directory, then permissions on all related hard links may be altered.
+--
+-- If an entry within the directory vanishes while @removePathForcibly@ is
+-- running, it is silently ignored.
+--
+-- If an exception occurs while removing an entry, @removePathForcibly@ will
+-- still try to remove as many entries as it can before failing with an
+-- exception.  The first exception that it encountered is re-thrown.
+removePathForcibly :: OsPath -> IO ()
+removePathForcibly path =
+  (`ioeAddLocation` "removePathForcibly") `modifyIOError` do
+    removeRecursivelyAt
+      ignoreDoesNotExistError
+      sequenceWithIOErrors_
+      forcePreremover
+      Nothing
+      path
+
+  where
+
+    ignoreDoesNotExistError :: IO () -> IO ()
+    ignoreDoesNotExistError action =
+      () <$ tryIOErrorType isDoesNotExistError action
+
+{- |'removeFile' /file/ removes the directory entry for an existing file
+/file/, where /file/ is not itself a directory. The
+implementation may specify additional constraints which must be
+satisfied before a file can be removed (e.g. the file may not be in
+use by other processes).
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+The operand is not a valid file name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The file does not exist.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY]@
+
+* @InappropriateType@
+The operand refers to an existing directory.
+@[EPERM, EINVAL]@
+
+-}
+
+removeFile :: OsPath -> IO ()
+removeFile = removePathInternal False
+
+{- |@'renameDirectory' old new@ changes the name of an existing
+directory from /old/ to /new/.  If the /new/ directory
+already exists, it is atomically replaced by the /old/ directory.
+If the /new/ directory is neither the /old/ directory nor an
+alias of the /old/ directory, it is removed as if by
+'removeDirectory'.  A conformant implementation need not support
+renaming directories in all situations (e.g. renaming to an existing
+directory, or across different physical devices), but the constraints
+must be documented.
+
+On Win32 platforms, @renameDirectory@ fails if the /new/ directory already
+exists.
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+Either operand is not a valid directory name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The original directory does not exist, or there is no path to the target.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* 'System.IO.isFullError'
+Insufficient resources are available to perform the operation.
+@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY, ENOTEMPTY, EEXIST]@
+
+* @UnsupportedOperation@
+The implementation does not support renaming in this situation.
+@[EINVAL, EXDEV]@
+
+* @InappropriateType@
+Either path refers to an existing non-directory object.
+@[ENOTDIR, EISDIR]@
+
+-}
+
+renameDirectory :: OsPath -> OsPath -> IO ()
+renameDirectory opath npath =
+   (`ioeAddLocation` "renameDirectory") `modifyIOError` do
+     -- XXX this test isn't performed atomically with the following rename
+     isDir <- pathIsDirectory opath
+     when (not isDir) . ioError $
+       mkIOError InappropriateType "renameDirectory" Nothing Nothing
+       `ioeSetErrorString` "not a directory"
+       `ioeSetOsPath` opath
+     renamePath opath npath
+
+{- |@'renameFile' old new@ changes the name of an existing file system
+object from /old/ to /new/.  If the /new/ object already exists, it is
+replaced by the /old/ object.  Neither path may refer to an existing
+directory.
+
+A conformant implementation need not support renaming files in all situations
+(e.g. renaming across different physical devices), but the constraints must be
+documented. On Windows, this does not support renaming across different physical
+devices; if you are looking to do so, consider using 'copyFileWithMetadata' and
+'removeFile'.
+
+On Windows, this calls @MoveFileEx@ with @MOVEFILE_REPLACE_EXISTING@ set,
+which is not guaranteed to be atomic
+(<https://github.com/haskell/directory/issues/109>).
+
+On other platforms, this operation is atomic.
+
+The operation may fail with:
+
+* @HardwareFault@
+A physical I\/O error has occurred.
+@[EIO]@
+
+* @InvalidArgument@
+Either operand is not a valid file name.
+@[ENAMETOOLONG, ELOOP]@
+
+* 'isDoesNotExistError'
+The original file does not exist, or there is no path to the target.
+@[ENOENT, ENOTDIR]@
+
+* 'isPermissionError'
+The process has insufficient privileges to perform the operation.
+@[EROFS, EACCES, EPERM]@
+
+* 'System.IO.isFullError'
+Insufficient resources are available to perform the operation.
+@[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+
+* @UnsatisfiedConstraints@
+Implementation-dependent constraints are not satisfied.
+@[EBUSY]@
+
+* @UnsupportedOperation@
+The implementation does not support renaming in this situation.
+@[EXDEV]@
+
+* @InappropriateType@
+Either path refers to an existing directory.
+@[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]@
+
+-}
+
+renameFile :: OsPath -> OsPath -> IO ()
+renameFile opath npath =
+  (`ioeAddLocation` "renameFile") `modifyIOError` do
+    -- XXX the tests are not performed atomically with the rename
+    checkNotDir opath
+    renamePath opath npath
+      -- The underlying rename implementation can throw odd exceptions when the
+      -- destination is a directory.  For example, Windows typically throws a
+      -- permission error, while POSIX systems may throw a resource busy error
+      -- if one of the paths refers to the current directory.  In these cases,
+      -- we check if the destination is a directory and, if so, throw an
+      -- InappropriateType error.
+      `catchIOError` \ err -> do
+        checkNotDir npath
+        ioError err
+  where checkNotDir path = do
+          m <- tryIOError (getSymbolicLinkMetadata path)
+          case fileTypeIsDirectory . fileTypeFromMetadata <$> m of
+            Right True ->
+              ioError $
+              mkIOError InappropriateType "" Nothing Nothing
+              `ioeSetErrorString` "is a directory"
+              `ioeSetOsPath` path
+            _          -> pure ()
+
+-- | Rename a file or directory.  If the destination path already exists, it
+-- is replaced atomically.  The destination path must not point to an existing
+-- directory.  A conformant implementation need not support renaming files in
+-- all situations (e.g. renaming across different physical devices), but the
+-- constraints must be documented.
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+-- A physical I\/O error has occurred.
+-- @[EIO]@
+--
+-- * @InvalidArgument@
+-- Either operand is not a valid file name.
+-- @[ENAMETOOLONG, ELOOP]@
+--
+-- * 'isDoesNotExistError'
+-- The original file does not exist, or there is no path to the target.
+-- @[ENOENT, ENOTDIR]@
+--
+-- * 'isPermissionError'
+-- The process has insufficient privileges to perform the operation.
+-- @[EROFS, EACCES, EPERM]@
+--
+-- * 'System.IO.isFullError'
+-- Insufficient resources are available to perform the operation.
+-- @[EDQUOT, ENOSPC, ENOMEM, EMLINK]@
+--
+-- * @UnsatisfiedConstraints@
+-- Implementation-dependent constraints are not satisfied.
+-- @[EBUSY]@
+--
+-- * @UnsupportedOperation@
+-- The implementation does not support renaming in this situation.
+-- @[EXDEV]@
+--
+-- * @InappropriateType@
+-- Either the destination path refers to an existing directory, or one of the
+-- parent segments in the destination path is not a directory.
+-- @[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]@
+renamePath :: OsPath                  -- ^ Old path
+           -> OsPath                  -- ^ New path
+           -> IO ()
+renamePath opath npath =
+  (`ioeAddLocation` "renamePath") `modifyIOError` do
+    renamePathInternal opath npath
+
+-- | Copy a file with its permissions.  If the destination file already exists,
+-- it is replaced atomically.  Neither path may refer to an existing
+-- directory.  No exceptions are thrown if the permissions could not be
+-- copied.
+copyFile :: OsPath                    -- ^ Source filename
+         -> OsPath                    -- ^ Destination filename
+         -> IO ()
+copyFile fromFPath toFPath =
+  (`ioeAddLocation` "copyFile") `modifyIOError` do
+    atomicCopyFileContents fromFPath toFPath
+      (ignoreIOExceptions . copyPermissions fromFPath)
+
+-- | Copy all data from a file to a handle.
+copyFileToHandle :: OsPath              -- ^ Source file
+                 -> Handle              -- ^ Destination handle
+                 -> IO ()
+copyFileToHandle fromFPath hTo =
+  (`ioeAddLocation` "copyFileToHandle") `modifyIOError` do
+    withBinaryFile fromFPath ReadMode $ \ hFrom ->
+      copyHandleData hFrom hTo
+
+-- | Copy the contents of a source file to a destination file, replacing the
+-- destination file atomically via @withReplacementFile@, resetting the
+-- attributes of the destination file to the defaults.
+atomicCopyFileContents :: OsPath            -- ^ Source filename
+                       -> OsPath            -- ^ Destination filename
+                       -> (OsPath -> IO ()) -- ^ Post-action
+                       -> IO ()
+atomicCopyFileContents fromFPath toFPath postAction =
+  (`ioeAddLocation` "atomicCopyFileContents") `modifyIOError` do
+    withReplacementFile toFPath postAction $ \ hTo -> do
+      copyFileToHandle fromFPath hTo
+
+-- | A helper function useful for replacing files in an atomic manner.  The
+-- function creates a temporary file in the directory of the destination file,
+-- opens it, performs the main action with its handle, closes it, performs the
+-- post-action with its path, and finally replaces the destination file with
+-- the temporary file.  If an error occurs during any step of this process,
+-- the temporary file is removed and the destination file remains untouched.
+withReplacementFile :: OsPath            -- ^ Destination file
+                    -> (OsPath -> IO ()) -- ^ Post-action
+                    -> (Handle -> IO a)  -- ^ Main action
+                    -> IO a
+withReplacementFile path postAction action =
+  (`ioeAddLocation` "withReplacementFile") `modifyIOError` do
+    mask $ \ restore -> do
+      let tmpPath = case encodeWith (mkUTF8 ErrorOnCodingFailure)
+                                    (mkUTF16le ErrorOnCodingFailure)
+                                    ".copyFile.tmp"
+                         of
+            Left err ->
+              error ("withReplacementFile: invalid encoding: " <> show err)
+            Right p -> p
+      let dir = takeDirectory path
+      (tmpFPath, hTmp) <-
+        openTempFile' "openTempFile'" dir tmpPath True 0o600 True
+      (`onException` ignoreIOExceptions (removeFile tmpFPath)) $ do
+        r <- (`onException` ignoreIOExceptions (hClose hTmp)) $ do
+          restore (action hTmp)
+        hClose hTmp
+        restore (postAction tmpFPath)
+        renameFile tmpFPath path
+        pure r
+
+-- | Copy a file with its associated metadata.  If the destination file
+-- already exists, it is overwritten.  There is no guarantee of atomicity in
+-- the replacement of the destination file.  Neither path may refer to an
+-- existing directory.  If the source and/or destination are symbolic links,
+-- the copy is performed on the targets of the links.
+--
+-- On Windows, it behaves like the Win32 function
+-- <https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851.aspx CopyFile>,
+-- which copies various kinds of metadata including file attributes and
+-- security resource properties.
+--
+-- On Unix-like systems, permissions, access time, and modification time are
+-- preserved.  If possible, the owner and group are also preserved.  Note that
+-- the very act of copying can change the access time of the source file,
+-- hence the access times of the two files may differ after the operation
+-- completes.
+copyFileWithMetadata :: OsPath        -- ^ Source file
+                     -> OsPath        -- ^ Destination file
+                     -> IO ()
+copyFileWithMetadata src dst =
+  (`ioeAddLocation` "copyFileWithMetadata") `modifyIOError`
+    copyFileWithMetadataInternal copyPermissionsFromMetadata
+                                 copyTimesFromMetadata
+                                 src
+                                 dst
+
+copyTimesFromMetadata :: Metadata -> OsPath -> IO ()
+copyTimesFromMetadata st dst = do
+  let atime = accessTimeFromMetadata st
+  let mtime = modificationTimeFromMetadata st
+  setFileTimes dst (Just atime, Just mtime)
+
+-- | Make a path absolute, normalize the path, and remove as many indirections
+-- from it as possible.  Any trailing path separators are discarded via
+-- 'dropTrailingPathSeparator'.  Additionally, on Windows the letter case of
+-- the path is canonicalized.
+--
+-- __Note__: This function is a very big hammer.  If you only need an absolute
+-- path, 'makeAbsolute' is sufficient for removing dependence on the current
+-- working directory.
+--
+-- Indirections include the two special directories @.@ and @..@, as well as
+-- any symbolic links (and junction points on Windows).  The input path need
+-- not point to an existing file or directory.  Canonicalization is performed
+-- on the longest prefix of the path that points to an existing file or
+-- directory.  The remaining portion of the path that does not point to an
+-- existing file or directory will still be normalized, but case
+-- canonicalization and indirection removal are skipped as they are impossible
+-- to do on a nonexistent path.
+--
+-- Most programs should not worry about the canonicity of a path.  In
+-- particular, despite the name, the function does not truly guarantee
+-- canonicity of the returned path due to the presence of hard links, mount
+-- points, etc.
+--
+-- If the path points to an existing file or directory, then the output path
+-- shall also point to the same file or directory, subject to the condition
+-- that the relevant parts of the file system do not change while the function
+-- is still running.  In other words, the function is definitively not atomic.
+-- The results can be utterly wrong if the portions of the path change while
+-- this function is running.
+--
+-- Since some indirections (symbolic links on all systems, @..@ on non-Windows
+-- systems, and junction points on Windows) are dependent on the state of the
+-- existing filesystem, the function can only make a conservative attempt by
+-- removing such indirections from the longest prefix of the path that still
+-- points to an existing file or directory.
+--
+-- Note that on Windows parent directories @..@ are always fully expanded
+-- before the symbolic links, as consistent with the rest of the Windows API
+-- (such as @GetFullPathName@).  In contrast, on POSIX systems parent
+-- directories @..@ are expanded alongside symbolic links from left to right.
+-- To put this more concretely: if @L@ is a symbolic link for @R/P@, then on
+-- Windows @L\\..@ refers to @.@, whereas on other operating systems @L/..@
+-- refers to @R@.
+--
+-- Similar to 'System.FilePath.normalise', passing an empty path is equivalent
+-- to passing the current directory.
+--
+-- @canonicalizePath@ can resolve at least 64 indirections in a single path,
+-- more than what is supported by most operating systems.  Therefore, it may
+-- return the fully resolved path even though the operating system itself
+-- would have long given up.
+--
+-- On Windows XP or earlier systems, junction expansion is not performed due
+-- to their lack of @GetFinalPathNameByHandle@.
+--
+-- /Changes since 1.2.3.0:/ The function has been altered to be more robust
+-- and has the same exception behavior as 'makeAbsolute'.
+--
+-- /Changes since 1.3.0.0:/ The function no longer preserves the trailing path
+-- separator.  File symbolic links that appear in the middle of a path are
+-- properly dereferenced.  Case canonicalization and symbolic link expansion
+-- are now performed on Windows.
+--
+canonicalizePath :: OsPath -> IO OsPath
+canonicalizePath = \ path ->
+  ((`ioeAddLocation` "canonicalizePath") .
+   (`ioeSetOsPath` path)) `modifyIOError` do
+    -- simplify does more stuff, like upper-casing the drive letter
+    dropTrailingPathSeparator . simplify <$>
+      (attemptRealpath realPath =<< prependCurrentDirectory path)
+  where
+
+    -- allow up to 64 cycles before giving up
+    attemptRealpath realpath =
+      attemptRealpathWith (64 :: Int) Nothing realpath
+      <=< canonicalizePathSimplify
+
+    -- n is a counter to make sure we don't run into an infinite loop; we
+    -- don't try to do any cycle detection here because an adversary could DoS
+    -- any arbitrarily clever algorithm
+    attemptRealpathWith n mFallback realpath path =
+      case mFallback of
+        -- too many indirections ... giving up.
+        Just fallback | n <= 0 -> pure fallback
+        -- either mFallback == Nothing (first attempt)
+        --     or n > 0 (still have some attempts left)
+        _ -> realpathPrefix (reverse (zip prefixes suffixes))
+
+      where
+
+        segments = splitDirectories path
+        prefixes = scanl1 (</>) segments
+        suffixes = NE.tail (NE.scanr (</>) mempty segments)
+
+        -- try to call realpath on the largest possible prefix
+        realpathPrefix candidates =
+          case candidates of
+            [] -> pure path
+            (prefix, suffix) : rest -> do
+              exist <- doesPathExist prefix
+              if not exist
+                -- never call realpath on an inaccessible path
+                -- (to avoid bugs in system realpath implementations)
+                -- try a smaller prefix instead
+                then realpathPrefix rest
+                else do
+                  mp <- tryIOError (realpath prefix)
+                  case mp of
+                    -- realpath failed: try a smaller prefix instead
+                    Left _ -> realpathPrefix rest
+                    -- realpath succeeded: fine-tune the result
+                    Right p -> realpathFurther (p </> suffix) p suffix
+
+        -- by now we have a reasonable fallback value that we can use if we
+        -- run into too many indirections; the fallback value is the same
+        -- result that we have been returning in versions prior to 1.3.1.0
+        -- (this is essentially the fix to #64)
+        realpathFurther fallback p suffix =
+          case splitDirectories suffix of
+            [] -> pure fallback
+            next : restSuffix -> do
+              -- see if the 'next' segment is a symlink
+              mTarget <- tryIOError (getSymbolicLinkTarget (p </> next))
+              case mTarget of
+                Left _ -> pure fallback
+                Right target -> do
+                  -- if so, dereference it and restart the whole cycle
+                  let mFallback' = Just (fromMaybe fallback mFallback)
+                  path' <- canonicalizePathSimplify
+                             (p </> target </> joinPath restSuffix)
+                  attemptRealpathWith (n - 1) mFallback' realpath path'
+
+-- | Convert a path into an absolute path.  If the given path is relative, the
+-- current directory is prepended and then the combined result is normalized.
+-- If the path is already absolute, the path is simply normalized.  The
+-- function preserves the presence or absence of the trailing path separator
+-- unless the path refers to the root directory @/@.
+--
+-- If the path is already absolute, the operation never fails.  Otherwise, the
+-- operation may fail with the same exceptions as 'getCurrentDirectory'.
+--
+makeAbsolute :: OsPath -> IO OsPath
+makeAbsolute path =
+  ((`ioeAddLocation` "makeAbsolute") .
+   (`ioeSetOsPath` path)) `modifyIOError` do
+    matchTrailingSeparator path . simplify <$> prependCurrentDirectory path
+
+-- | Add or remove the trailing path separator in the second path so as to
+-- match its presence in the first path.
+--
+-- (internal API)
+matchTrailingSeparator :: OsPath -> OsPath -> OsPath
+matchTrailingSeparator path
+  | hasTrailingPathSeparator path = addTrailingPathSeparator
+  | otherwise                     = dropTrailingPathSeparator
+
+-- | Construct a path relative to the current directory, similar to
+-- 'makeRelative'.
+--
+-- The operation may fail with the same exceptions as 'getCurrentDirectory'.
+makeRelativeToCurrentDirectory :: OsPath -> IO OsPath
+makeRelativeToCurrentDirectory x = do
+  (`makeRelative` x) <$> getCurrentDirectory
+
+-- | Given the name or path of an executable file, 'findExecutable' searches
+-- for such a file in a list of system-defined locations, which generally
+-- includes @PATH@ and possibly more.  The full path to the executable is
+-- returned if found.  For example, @(findExecutable \"ghc\")@ would normally
+-- give you the path to GHC.
+--
+-- The path returned by @'findExecutable' name@ corresponds to the program
+-- that would be executed by
+-- @<http://hackage.haskell.org/package/process/docs/System-Process.html#v:createProcess createProcess>@
+-- when passed the same string (as a @RawCommand@, not a @ShellCommand@),
+-- provided that @name@ is not a relative path with more than one segment.
+--
+-- On Windows, 'findExecutable' calls the Win32 function
+-- @<https://msdn.microsoft.com/en-us/library/aa365527.aspx SearchPath>@,
+-- which may search other places before checking the directories in the @PATH@
+-- environment variable.  Where it actually searches depends on registry
+-- settings, but notably includes the directory containing the current
+-- executable.
+--
+-- On non-Windows platforms, the behavior is equivalent to 'findFileWith'
+-- using the search directories from the @PATH@ environment variable and
+-- testing each file for executable permissions.  Details can be found in the
+-- documentation of 'findFileWith'.
+findExecutable :: OsString -> IO (Maybe OsPath)
+findExecutable binary =
+  listTHead
+    (findExecutablesLazyInternal findExecutablesInDirectoriesLazy binary)
+
+-- | Search for executable files in a list of system-defined locations, which
+-- generally includes @PATH@ and possibly more.
+--
+-- On Windows, this /only returns the first occurrence/, if any.  Its behavior
+-- is therefore equivalent to 'findExecutable'.
+--
+-- On non-Windows platforms, the behavior is equivalent to
+-- 'findExecutablesInDirectories' using the search directories from the @PATH@
+-- environment variable.  Details can be found in the documentation of
+-- 'findExecutablesInDirectories'.
+findExecutables :: OsString -> IO [OsPath]
+findExecutables binary =
+  listTToList
+    (findExecutablesLazyInternal findExecutablesInDirectoriesLazy binary)
+
+-- | Given a name or path, 'findExecutable' appends the 'exeExtension' to the
+-- query and searches for executable files in the list of given search
+-- directories and returns all occurrences.
+--
+-- The behavior is equivalent to 'findFileWith' using the given search
+-- directories and testing each file for executable permissions.  Details can
+-- be found in the documentation of 'findFileWith'.
+--
+-- Unlike other similarly named functions, 'findExecutablesInDirectories' does
+-- not use @SearchPath@ from the Win32 API.  The behavior of this function on
+-- Windows is therefore equivalent to those on non-Windows platforms.
+findExecutablesInDirectories :: [OsPath] -> OsString -> IO [OsPath]
+findExecutablesInDirectories path binary =
+  listTToList (findExecutablesInDirectoriesLazy path binary)
+
+findExecutablesInDirectoriesLazy :: [OsPath] -> OsString -> ListT IO OsPath
+findExecutablesInDirectoriesLazy path binary =
+  findFilesWithLazy isExecutable path (binary <.> exeExtension)
+
+-- | Test whether a file has executable permissions.
+isExecutable :: OsPath -> IO Bool
+isExecutable file = executable <$> getPermissions file
+
+-- | Search through the given list of directories for the given file.
+--
+-- The behavior is equivalent to 'findFileWith', returning only the first
+-- occurrence.  Details can be found in the documentation of 'findFileWith'.
+findFile :: [OsPath] -> OsString -> IO (Maybe OsPath)
+findFile = findFileWith (\ _ -> pure True)
+
+-- | Search through the given list of directories for the given file and
+-- returns all paths where the given file exists.
+--
+-- The behavior is equivalent to 'findFilesWith'.  Details can be found in the
+-- documentation of 'findFilesWith'.
+findFiles :: [OsPath] -> OsString -> IO [OsPath]
+findFiles = findFilesWith (\ _ -> pure True)
+
+-- | Search through a given list of directories for a file that has the given
+-- name and satisfies the given predicate and return the path of the first
+-- occurrence.  The directories are checked in a left-to-right order.
+--
+-- This is essentially a more performant version of 'findFilesWith' that
+-- always returns the first result, if any.  Details can be found in the
+-- documentation of 'findFilesWith'.
+findFileWith :: (OsPath -> IO Bool) -> [OsPath] -> OsString -> IO (Maybe OsPath)
+findFileWith f ds name = listTHead (findFilesWithLazy f ds name)
+
+-- | @findFilesWith predicate dirs name@ searches through the list of
+-- directories (@dirs@) for files that have the given @name@ and satisfy the
+-- given @predicate@ and returns the paths of those files.  The directories
+-- are checked in a left-to-right order and the paths are returned in the same
+-- order.
+--
+-- If the @name@ is a relative path, then for every search directory @dir@,
+-- the function checks whether @dir '</>' name@ exists and satisfies the
+-- predicate.  If so, @dir '</>' name@ is returned as one of the results.  In
+-- other words, the returned paths can be either relative or absolute
+-- depending on the search directories were used.  If there are no search
+-- directories, no results are ever returned.
+--
+-- If the @name@ is an absolute path, then the function will return a single
+-- result if the file exists and satisfies the predicate and no results
+-- otherwise.  This is irrespective of what search directories were given.
+findFilesWith :: (OsPath -> IO Bool) -> [OsPath] -> OsString -> IO [OsPath]
+findFilesWith f ds name = listTToList (findFilesWithLazy f ds name)
+
+findFilesWithLazy
+  :: (OsPath -> IO Bool) -> [OsPath] -> OsString -> ListT IO OsPath
+findFilesWithLazy f dirs path
+  -- make sure absolute paths are handled properly irrespective of 'dirs'
+  -- https://github.com/haskell/directory/issues/72
+  | isAbsolute path = ListT (find [mempty])
+  | otherwise       = ListT (find dirs)
+
+  where
+
+    find []       = pure Nothing
+    find (d : ds) = do
+      let p = d </> path
+      found <- doesFileExist p `andM` f p
+      if found
+        then pure (Just (p, ListT (find ds)))
+        else find ds
+
+-- | Filename extension for executable files (including the dot if any)
+--   (usually @\"\"@ on POSIX systems and @\".exe\"@ on Windows or OS\/2).
+exeExtension :: OsString
+exeExtension = exeExtensionInternal
+
+-- | Similar to 'listDirectory', but always includes the special entries (@.@
+-- and @..@).  (This applies to Windows as well.)
+--
+-- The operation may fail with the same exceptions as 'listDirectory'.
+getDirectoryContents :: OsPath -> IO [OsPath]
+getDirectoryContents path =
+  ((`ioeSetOsPath` path) .
+   (`ioeAddLocation` "getDirectoryContents")) `modifyIOError` do
+    getDirectoryContentsInternal path
+
+-- | @'listDirectory' dir@ returns a list of /all/ entries in /dir/ without
+-- the special entries (@.@ and @..@).
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+--   A physical I\/O error has occurred.
+--   @[EIO]@
+--
+-- * @InvalidArgument@
+--   The operand is not a valid directory name.
+--   @[ENAMETOOLONG, ELOOP]@
+--
+-- * 'isDoesNotExistError'
+--   The directory does not exist.
+--   @[ENOENT, ENOTDIR]@
+--
+-- * 'isPermissionError'
+--   The process has insufficient privileges to perform the operation.
+--   @[EACCES]@
+--
+-- * 'System.IO.isFullError'
+--   Insufficient resources are available to perform the operation.
+--   @[EMFILE, ENFILE]@
+--
+-- * @InappropriateType@
+--   The path refers to an existing non-directory object.
+--   @[ENOTDIR]@
+--
+listDirectory :: OsPath -> IO [OsPath]
+listDirectory path = dropSpecialDotDirs <$> getDirectoryContents path
+
+-- | Obtain the current working directory as an absolute path.
+--
+-- In a multithreaded program, the current working directory is a global state
+-- shared among all threads of the process.  Therefore, when performing
+-- filesystem operations from multiple threads, it is highly recommended to
+-- use absolute rather than relative paths (see: 'makeAbsolute').
+--
+-- Note that 'getCurrentDirectory' is not guaranteed to return the same path
+-- received by 'setCurrentDirectory'. On POSIX systems, the path returned will
+-- always be fully dereferenced (not contain any symbolic links). For more
+-- information, refer to the documentation of
+-- <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html getcwd>.
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+-- A physical I\/O error has occurred.
+-- @[EIO]@
+--
+-- * 'isDoesNotExistError'
+-- There is no path referring to the working directory.
+-- @[EPERM, ENOENT, ESTALE...]@
+--
+-- * 'isPermissionError'
+-- The process has insufficient privileges to perform the operation.
+-- @[EACCES]@
+--
+-- * 'System.IO.isFullError'
+-- Insufficient resources are available to perform the operation.
+--
+-- * @UnsupportedOperation@
+-- The operating system has no notion of current working directory.
+--
+getCurrentDirectory :: IO OsPath
+getCurrentDirectory =
+  (`ioeAddLocation` "getCurrentDirectory") `modifyIOError` do
+    specializeErrorString
+      "Current working directory no longer exists"
+      isDoesNotExistError
+      getCurrentDirectoryInternal
+
+-- | Change the working directory to the given path.
+--
+-- In a multithreaded program, the current working directory is a global state
+-- shared among all threads of the process.  Therefore, when performing
+-- filesystem operations from multiple threads, it is highly recommended to
+-- use absolute rather than relative paths (see: 'makeAbsolute').
+--
+-- The operation may fail with:
+--
+-- * @HardwareFault@
+-- A physical I\/O error has occurred.
+-- @[EIO]@
+--
+-- * @InvalidArgument@
+-- The operand is not a valid directory name.
+-- @[ENAMETOOLONG, ELOOP]@
+--
+-- * 'isDoesNotExistError'
+-- The directory does not exist.
+-- @[ENOENT, ENOTDIR]@
+--
+-- * 'isPermissionError'
+-- The process has insufficient privileges to perform the operation.
+-- @[EACCES]@
+--
+-- * @UnsupportedOperation@
+-- The operating system has no notion of current working directory, or the
+-- working directory cannot be dynamically changed.
+--
+-- * @InappropriateType@
+-- The path refers to an existing non-directory object.
+-- @[ENOTDIR]@
+--
+setCurrentDirectory :: OsPath -> IO ()
+setCurrentDirectory = setCurrentDirectoryInternal
+
+-- | Run an 'IO' action with the given working directory and restore the
+-- original working directory afterwards, even if the given action fails due
+-- to an exception.
+--
+-- The operation may fail with the same exceptions as 'getCurrentDirectory'
+-- and 'setCurrentDirectory'.
+--
+withCurrentDirectory :: OsPath    -- ^ Directory to execute in
+                     -> IO a      -- ^ Action to be executed
+                     -> IO a
+withCurrentDirectory dir action =
+  bracket getCurrentDirectory setCurrentDirectory $ \ _ -> do
+    setCurrentDirectory dir
+    action
+
+-- | Obtain the size of a file in bytes.
+getFileSize :: OsPath -> IO Integer
+getFileSize path =
+  (`ioeAddLocation` "getFileSize") `modifyIOError` do
+    fileSizeFromMetadata <$> getFileMetadata path
+
+-- | Test whether the given path points to an existing filesystem object.  If
+-- the user lacks necessary permissions to search the parent directories, this
+-- function may return false even if the file does actually exist.  This
+-- operation traverses symbolic links, so it can return either True or False
+-- for them.
+doesPathExist :: OsPath -> IO Bool
+doesPathExist path = do
+  (True <$ getFileMetadata path)
+    `catchIOError` \ _ ->
+      pure False
+
+-- | The operation 'doesDirectoryExist' returns 'True' if the argument file
+-- exists and is either a directory or a symbolic link to a directory, and
+-- 'False' otherwise.  This operation traverses symbolic links, so it can
+-- return either True or False for them.
+doesDirectoryExist :: OsPath -> IO Bool
+doesDirectoryExist path = do
+  pathIsDirectory path
+    `catchIOError` \ _ ->
+      pure False
+
+-- | The operation 'doesFileExist' returns 'True' if the argument file exists
+-- and is not a directory, and 'False' otherwise.  This operation traverses
+-- symbolic links, so it can return either True or False for them.
+doesFileExist :: OsPath -> IO Bool
+doesFileExist path = do
+  (not <$> pathIsDirectory path)
+    `catchIOError` \ _ ->
+      pure False
+
+pathIsDirectory :: OsPath -> IO Bool
+pathIsDirectory path =
+  (`ioeAddLocation` "pathIsDirectory") `modifyIOError` do
+    fileTypeIsDirectory . fileTypeFromMetadata <$> getFileMetadata path
+
+-- | Create a /file/ symbolic link.  The target path can be either absolute or
+-- relative and need not refer to an existing file.  The order of arguments
+-- follows the POSIX convention.
+--
+-- To remove an existing file symbolic link, use 'removeFile'.
+--
+-- Although the distinction between /file/ symbolic links and /directory/
+-- symbolic links does not exist on POSIX systems, on Windows this is an
+-- intrinsic property of every symbolic link and cannot be changed without
+-- recreating the link.  A file symbolic link that actually points to a
+-- directory will fail to dereference and vice versa.  Moreover, creating
+-- symbolic links on Windows may require privileges unavailable to users
+-- outside the Administrators group.  Portable programs that use symbolic
+-- links should take both into consideration.
+--
+-- On Windows, the function is implemented using @CreateSymbolicLink@.  Since
+-- 1.3.3.0, the @SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE@ flag is included
+-- if supported by the operating system.  On POSIX, the function uses @symlink@
+-- and is therefore atomic.
+--
+-- Windows-specific errors: This operation may fail with 'permissionErrorType'
+-- if the user lacks the privileges to create symbolic links.  It may also
+-- fail with 'illegalOperationErrorType' if the file system does not support
+-- symbolic links.
+createFileLink
+  :: OsPath                           -- ^ path to the target file
+  -> OsPath                           -- ^ path of the link to be created
+  -> IO ()
+createFileLink target link =
+  (`ioeAddLocation` "createFileLink") `modifyIOError` do
+    createSymbolicLink False target link
+
+-- | Create a /directory/ symbolic link.  The target path can be either
+-- absolute or relative and need not refer to an existing directory.  The
+-- order of arguments follows the POSIX convention.
+--
+-- To remove an existing directory symbolic link, use 'removeDirectoryLink'.
+--
+-- Although the distinction between /file/ symbolic links and /directory/
+-- symbolic links does not exist on POSIX systems, on Windows this is an
+-- intrinsic property of every symbolic link and cannot be changed without
+-- recreating the link.  A file symbolic link that actually points to a
+-- directory will fail to dereference and vice versa.  Moreover, creating
+-- symbolic links on Windows may require privileges unavailable to users
+-- outside the Administrators group.  Portable programs that use symbolic
+-- links should take both into consideration.
+--
+-- On Windows, the function is implemented using @CreateSymbolicLink@ with
+-- @SYMBOLIC_LINK_FLAG_DIRECTORY@.  Since 1.3.3.0, the
+-- @SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE@ flag is also included if
+-- supported by the operating system.   On POSIX, this is an alias for
+-- 'createFileLink' and is therefore atomic.
+--
+-- Windows-specific errors: This operation may fail with 'permissionErrorType'
+-- if the user lacks the privileges to create symbolic links.  It may also
+-- fail with 'illegalOperationErrorType' if the file system does not support
+-- symbolic links.
+createDirectoryLink
+  :: OsPath                           -- ^ path to the target directory
+  -> OsPath                           -- ^ path of the link to be created
+  -> IO ()
+createDirectoryLink target link =
+  (`ioeAddLocation` "createDirectoryLink") `modifyIOError` do
+    createSymbolicLink True target link
+
+-- | Remove an existing /directory/ symbolic link.
+--
+-- On Windows, this is an alias for 'removeDirectory'.  On POSIX systems, this
+-- is an alias for 'removeFile'.
+--
+-- See also: 'removeFile', which can remove an existing /file/ symbolic link.
+removeDirectoryLink :: OsPath -> IO ()
+removeDirectoryLink path =
+  (`ioeAddLocation` "removeDirectoryLink") `modifyIOError` do
+    removePathInternal linkToDirectoryIsDirectory path
+
+-- | Check whether an existing @path@ is a symbolic link.  If @path@ is a
+-- regular file or directory, 'False' is returned.  If @path@ does not exist
+-- or is otherwise inaccessible, an exception is thrown (see below).
+--
+-- On Windows, this checks for @FILE_ATTRIBUTE_REPARSE_POINT@.  In addition to
+-- symbolic links, the function also returns true on junction points.  On
+-- POSIX systems, this checks for @S_IFLNK@.
+--
+-- The operation may fail with:
+--
+-- * 'isDoesNotExistError' if the symbolic link does not exist; or
+--
+-- * 'isPermissionError' if the user is not permitted to read the symbolic
+--   link.
+pathIsSymbolicLink :: OsPath -> IO Bool
+pathIsSymbolicLink path =
+  ((`ioeAddLocation` "pathIsSymbolicLink") .
+   (`ioeSetOsPath` path)) `modifyIOError` do
+     fileTypeIsLink . fileTypeFromMetadata <$> getSymbolicLinkMetadata path
+
+-- | Retrieve the target path of either a file or directory symbolic link.
+-- The returned path may not be absolute, may not exist, and may not even be a
+-- valid path.
+--
+-- On Windows systems, this calls @DeviceIoControl@ with
+-- @FSCTL_GET_REPARSE_POINT@.  In addition to symbolic links, the function
+-- also works on junction points.  On POSIX systems, this calls @readlink@.
+--
+-- Windows-specific errors: This operation may fail with
+-- 'illegalOperationErrorType' if the file system does not support symbolic
+-- links.
+getSymbolicLinkTarget :: OsPath -> IO OsPath
+getSymbolicLinkTarget path =
+  (`ioeAddLocation` "getSymbolicLinkTarget") `modifyIOError` do
+    readSymbolicLink path
+
+-- | Obtain the time at which the file or directory was last accessed.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to read
+--   the access time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- Caveat for POSIX systems: This function returns a timestamp with sub-second
+-- resolution only if this package is compiled against @unix-2.6.0.0@ or later
+-- and the underlying filesystem supports them.
+--
+getAccessTime :: OsPath -> IO UTCTime
+getAccessTime path =
+  (`ioeAddLocation` "getAccessTime") `modifyIOError` do
+    accessTimeFromMetadata <$> getFileMetadata (emptyToCurDir path)
+
+-- | Obtain the time at which the file or directory was last modified.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to read
+--   the modification time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- Caveat for POSIX systems: This function returns a timestamp with sub-second
+-- resolution only if this package is compiled against @unix-2.6.0.0@ or later
+-- and the underlying filesystem supports them.
+--
+getModificationTime :: OsPath -> IO UTCTime
+getModificationTime path =
+  (`ioeAddLocation` "getModificationTime") `modifyIOError` do
+    modificationTimeFromMetadata <$> getFileMetadata (emptyToCurDir path)
+
+-- | Change the time at which the file or directory was last accessed.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to alter the
+--   access time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- Some caveats for POSIX systems:
+--
+-- * Not all systems support @utimensat@, in which case the function can only
+--   emulate the behavior by reading the modification time and then setting
+--   both the access and modification times together.  On systems where
+--   @utimensat@ is supported, the access time is set atomically with
+--   nanosecond precision.
+--
+-- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function
+--   would not be able to set timestamps with sub-second resolution.  In this
+--   case, there would also be loss of precision in the modification time.
+--
+setAccessTime :: OsPath -> UTCTime -> IO ()
+setAccessTime path atime =
+  (`ioeAddLocation` "setAccessTime") `modifyIOError` do
+    setFileTimes path (Just atime, Nothing)
+
+-- | Change the time at which the file or directory was last modified.
+--
+-- The operation may fail with:
+--
+-- * 'isPermissionError' if the user is not permitted to alter the
+--   modification time; or
+--
+-- * 'isDoesNotExistError' if the file or directory does not exist.
+--
+-- * 'InvalidArgument' on FAT32 file system if the time is before
+--   DOS Epoch (1 January 1980).
+--
+-- Some caveats for POSIX systems:
+--
+-- * Not all systems support @utimensat@, in which case the function can only
+--   emulate the behavior by reading the access time and then setting both the
+--   access and modification times together.  On systems where @utimensat@ is
+--   supported, the modification time is set atomically with nanosecond
+--   precision.
+--
+-- * If compiled against a version of @unix@ prior to @2.7.0.0@, the function
+--   would not be able to set timestamps with sub-second resolution.  In this
+--   case, there would also be loss of precision in the access time.
+--
+setModificationTime :: OsPath -> UTCTime -> IO ()
+setModificationTime path mtime =
+  (`ioeAddLocation` "setModificationTime") `modifyIOError` do
+    setFileTimes path (Nothing, Just mtime)
+
+setFileTimes :: OsPath -> (Maybe UTCTime, Maybe UTCTime) -> IO ()
+setFileTimes _ (Nothing, Nothing) = pure ()
+setFileTimes path (atime, mtime) =
+  ((`ioeAddLocation` "setFileTimes") .
+   (`ioeSetOsPath` path)) `modifyIOError` do
+    setTimes (emptyToCurDir path)
+             (utcTimeToPOSIXSeconds <$> atime, utcTimeToPOSIXSeconds <$> mtime)
+
+{- | Returns the current user's home directory.
+
+The directory returned is expected to be writable by the current user,
+but note that it isn't generally considered good practice to store
+application-specific data here; use 'getXdgDirectory' or
+'getAppUserDataDirectory' instead.
+
+On Unix, 'getHomeDirectory' behaves as follows:
+
+* Returns $HOME env variable if set (including to an empty string).
+* Otherwise uses home directory returned by @getpwuid_r@ using the UID of the
+  current process' user. This basically reads the @\/etc\/passwd@ file. An
+  empty home directory field is considered valid.
+
+On Windows, the system is queried for a suitable path; a typical path might be
+@C:\/Users\//\<user\>/@.
+
+The operation may fail with:
+
+* @UnsupportedOperation@
+The operating system has no notion of home directory.
+
+* 'isDoesNotExistError'
+The home directory for the current user does not exist, or
+cannot be found.
+-}
+getHomeDirectory :: IO OsPath
+getHomeDirectory =
+  (`ioeAddLocation` "getHomeDirectory") `modifyIOError` do
+    getHomeDirectoryInternal
+
+-- | Obtain the paths to special directories for storing user-specific
+--   application data, configuration, and cache files, conforming to the
+--   <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html XDG Base Directory Specification>.
+--   Compared with 'getAppUserDataDirectory', this function provides a more
+--   fine-grained hierarchy as well as greater flexibility for the user.
+--
+--   On Windows, 'XdgData' and 'XdgConfig' usually map to the same directory
+--   unless overridden.
+--
+--   Refer to the docs of 'XdgDirectory' for more details.
+--
+--   The second argument is usually the name of the application.  Since it
+--   will be integrated into the path, it must consist of valid path
+--   characters.  Note: if the second argument is an absolute path, it will
+--   just return the second argument.
+--
+--   Note: The directory may not actually exist, in which case you would need
+--   to create it with file mode @700@ (i.e. only accessible by the owner).
+--
+--   As of 1.3.5.0, the environment variable is ignored if set to a relative
+--   path, per revised XDG Base Directory Specification.  See
+--   <https://github.com/haskell/directory/issues/100 #100>.
+getXdgDirectory :: XdgDirectory         -- ^ which special directory
+                -> OsPath               -- ^ a relative path that is appended
+                                        --   to the path; if empty, the base
+                                        --   path is returned
+                -> IO OsPath
+getXdgDirectory xdgDir suffix =
+  (`ioeAddLocation` "getXdgDirectory") `modifyIOError` do
+    simplify . (</> suffix) <$> do
+      env <- lookupEnvOs $ case xdgDir of
+        XdgData   -> os "XDG_DATA_HOME"
+        XdgConfig -> os "XDG_CONFIG_HOME"
+        XdgCache  -> os "XDG_CACHE_HOME"
+        XdgState  -> os "XDG_STATE_HOME"
+      case env of
+        Just path | isAbsolute path -> pure path
+        _ -> getXdgDirectoryFallback getHomeDirectory xdgDir
+
+-- | Similar to 'getXdgDirectory' but retrieves the entire list of XDG
+-- directories.
+--
+-- On Windows, 'XdgDataDirs' and 'XdgConfigDirs' usually map to the same list
+-- of directories unless overridden.
+--
+-- Refer to the docs of 'XdgDirectoryList' for more details.
+getXdgDirectoryList :: XdgDirectoryList -- ^ which special directory list
+                    -> IO [OsPath]
+getXdgDirectoryList xdgDirs =
+  (`ioeAddLocation` "getXdgDirectoryList") `modifyIOError` do
+    env <- lookupEnvOs $ case xdgDirs of
+      XdgDataDirs   -> os "XDG_DATA_DIRS"
+      XdgConfigDirs -> os "XDG_CONFIG_DIRS"
+    case env of
+      Nothing    -> getXdgDirectoryListFallback xdgDirs
+      Just paths -> pure (splitSearchPath paths)
+
+-- | Obtain the path to a special directory for storing user-specific
+--   application data (traditional Unix location).  Newer applications may
+--   prefer the the XDG-conformant location provided by 'getXdgDirectory'
+--   (<https://github.com/haskell/directory/issues/6#issuecomment-96521020 migration guide>).
+--
+--   The argument is usually the name of the application.  Since it will be
+--   integrated into the path, it must consist of valid path characters.
+--
+--   * On Unix-like systems, the path is @~\/./\<app\>/@.
+--   * On Windows, the path is @%APPDATA%\//\<app\>/@
+--     (e.g. @C:\/Users\//\<user\>/\/AppData\/Roaming\//\<app\>/@)
+--
+--   Note: the directory may not actually exist, in which case you would need
+--   to create it.  It is expected that the parent directory exists and is
+--   writable.
+--
+--   The operation may fail with:
+--
+--   * @UnsupportedOperation@
+--     The operating system has no notion of application-specific data
+--     directory.
+--
+--   * 'isDoesNotExistError'
+--     The home directory for the current user does not exist, or cannot be
+--     found.
+--
+getAppUserDataDirectory :: OsPath     -- ^ a relative path that is appended
+                                        --   to the path
+                        -> IO OsPath
+getAppUserDataDirectory appName = do
+  (`ioeAddLocation` "getAppUserDataDirectory") `modifyIOError` do
+    getAppUserDataDirectoryInternal appName
+
+{- | Returns the current user's document directory.
+
+The directory returned is expected to be writable by the current user,
+but note that it isn't generally considered good practice to store
+application-specific data here; use 'getXdgDirectory' or
+'getAppUserDataDirectory' instead.
+
+On Unix, 'getUserDocumentsDirectory' returns the value of the @HOME@
+environment variable.  On Windows, the system is queried for a
+suitable path; a typical path might be @C:\/Users\//\<user\>/\/Documents@.
+
+The operation may fail with:
+
+* @UnsupportedOperation@
+The operating system has no notion of document directory.
+
+* 'isDoesNotExistError'
+The document directory for the current user does not exist, or
+cannot be found.
+-}
+getUserDocumentsDirectory :: IO OsPath
+getUserDocumentsDirectory = do
+  (`ioeAddLocation` "getUserDocumentsDirectory") `modifyIOError` do
+    getUserDocumentsDirectoryInternal
+
+{- | Returns the current directory for temporary files.
+
+On Unix, 'getTemporaryDirectory' returns the value of the @TMPDIR@
+environment variable or \"\/tmp\" if the variable isn\'t defined.
+On Windows, the function checks for the existence of environment variables in
+the following order and uses the first path found:
+
+*
+TMP environment variable.
+
+*
+TEMP environment variable.
+
+*
+USERPROFILE environment variable.
+
+*
+The Windows directory
+
+The operation may fail with:
+
+* @UnsupportedOperation@
+The operating system has no notion of temporary directory.
+
+The function doesn\'t verify whether the path exists.
+-}
+getTemporaryDirectory :: IO OsPath
+getTemporaryDirectory = getTemporaryDirectoryInternal
+
+-- | Get the contents of the @PATH@ environment variable.
+getExecSearchPath :: IO [OsPath]
+getExecSearchPath = getPath
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,13 +1,259 @@
 Changelog for the [`directory`][1] package
 ==========================================
 
+## 1.3.11.0 (May 2026)
+
+  * Cabal flag `os-string` was removed in favor of `impl(ghc >= 9.2)`.
+    ([#176](https://github.com/haskell/directory/issues/176))
+  * Enable close-on-exec flag when copying files and relax `file-io` version
+    bounds to support 0.2.0. Note that close-on-exec when copying is only
+    enabled on `file-io` 0.2.0 or later.
+    ([#203](https://github.com/haskell/directory/issues/203))
+  * Relax `time` version bounds to support 1.16.
+
+## 1.3.10.1 (Jan 2026)
+
+  * Make `findExecutable` return `Nothing` on absolute paths that aren't
+    executable.
+    ([#187](https://github.com/haskell/directory/issues/187))
+  * Ensure `removePathForcibly` removes write-protected files on all
+    platforms.
+    ([#194](https://github.com/haskell/directory/issues/194))
+
+## 1.3.10.0 (Dec 2025)
+
+  * Add `getExecSearchPath` as replacement for
+    `System.FilePath.getSearchPath`.
+    ([#198](https://github.com/haskell/directory/pull/198))
+  * The [extended-length prefix][extended-length prefix] (`\\?\`) is no longer
+    implicitly prepended to Windows UNC paths to avoid triggering a Win32
+    implementation bug. Clients using long UNC paths should find alternatives
+    to [enable long paths][enable long paths].
+    ([#206](https://github.com/haskell/directory/issues/206))
+
+[extended-length prefix]: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation#:~:text=%5C%5C%3F%5C
+[enable long paths]: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation#enable-long-paths-in-windows-10-version-1607-and-later
+
+## 1.3.9.0 (Oct 2024)
+
+  * Rely on `file-io` for file I/O.
+  * Drop support for `base` older than 4.12.0.
+  * Resolve TOCTOU issue with `removeDirectoryRecursive` and
+    `removePathForcibly` on POSIX systems.
+    (part of [#97](https://github.com/haskell/directory/issues/97))
+  * `findExecutable ""` now returns `Nothing`, matching non-Windows systems
+    ([#180](https://github.com/haskell/directory/issues/180))
+
+## 1.3.8.5 (May 2024)
+
+  * Fix regression that causes copying of nonexistent files to create empty
+    files.
+    ([#177](https://github.com/haskell/directory/issues/177))
+
+## 1.3.8.4 (Apr 2024)
+
+  * Relax `time` version bounds to support 1.14.
+    ([#171](https://github.com/haskell/directory/issues/171))
+  * Relax `base` version bounds to support 4.20.
+    ([#173](https://github.com/haskell/directory/issues/173))
+  * Relax `filepath` version bounds to support 1.4.300 when `os-string` is
+    unavailable.
+    ([#175](https://github.com/haskell/directory/issues/175))
+
+## 1.3.8.3 (Jan 2024)
+
+  * Relax `Win32` version bounds to support 2.14.0.0.
+    ([#166](https://github.com/haskell/directory/issues/166))
+  * Fix regression in `canonicalizePath` on Windows UNC paths.
+    ([#170](https://github.com/haskell/directory/issues/170))
+
+## 1.3.8.2 (Dec 2023)
+
+  * Relax `base` version bounds to support 4.19.
+    ([#157](https://github.com/haskell/directory/pull/157))
+  * Support filepath >= 1.5.0.0 and os-string.
+    ([#164](https://github.com/haskell/directory/issues/164))
+
+## 1.3.8.1 (Feb 2023)
+
+  * Use CApiFFI for utimensat.
+    ([#145](https://github.com/haskell/directory/pull/145))
+  * Relax `base` version bounds to support 4.18.
+    ([#151](https://github.com/haskell/directory/pull/151))
+
+## 1.3.8.0 (Sep 2022)
+
+  * Drop support for `base` older than 4.11.0.
+  * Drop support for `filepath` older than 1.4.100.
+  * Drop support for `time` older than 1.8.0.
+  * Drop support for `unix` older than 2.8.0.
+  * Drop support for `Win32` older than 2.13.3.
+  * Modules in `directory` are no longer considered
+    [Safe](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/safe_haskell.html)
+    because the `System.OsPath` dependency is no longer Safe.
+  * A new module, `System.Directory.OsPath`, has been introduced to support
+    AFPP (`OsPath` and `OsString`) with an analogous API. The old module,
+    `System.Directory`, shall be in maintenance mode as new features will no
+    longer be accepted there.
+    ([#136](https://github.com/haskell/directory/pull/136))
+  * `removePathForcibly` no longer changes permissions of files on non-Windows
+    systems.  ([#135](https://github.com/haskell/directory/issues/135))
+
+## 1.3.7.1 (Jul 2022)
+
+  * Relax `time` version bounds to support 1.12.
+  * Relax `Win32` version bounds to support 2.13.
+  * Relax `base` version bounds to support 4.17.
+
+## 1.3.7.0 (Sep 2021)
+
+  * `getXdgDirectory` now supports `XdgState` (`XDG_STATE_HOME`).
+    ([#121](https://github.com/haskell/directory/pull/121))
+
+## 1.3.6.2 (May 2021)
+
+  * Relax `Win32` version bounds to support 2.11.
+  * Relax `time` version bounds to support 1.11.
+  * Relax `base` version bounds to support 4.16.
+
+## 1.3.6.1 (March 2020)
+
+  * Relax `time` version bounds to support 1.10.
+
+## 1.3.6.0 (January 2020)
+
+  * On non-Windows platforms, `getHomeDirectory` will fall back to
+    `getpwuid_r` if `HOME` is not set.
+    ([#102](https://github.com/haskell/directory/issues/102))
+
+## 1.3.5.0 (December 2019)
+
+  * Revert change introduced in the version `1.3.3.2`: Non-absolute `XDG_*`
+    environment variables are ignored.  This behavior is according to
+    [*XDG Base Directory Specification* version 0.7](https://specifications.freedesktop.org/basedir-spec/0.7/ar01s02.html)
+    ([#100](https://github.com/haskell/directory/issues/100))
+
+## 1.3.4.0 (July 2019)
+
+  * `getXdgDirectory` and `getXdgDirectoryList` on Windows will now respect
+    the XDG environment variables if present.
+    ([#95](https://github.com/haskell/directory/issues/95))
+
+## 1.3.3.2 (January 2019)
+
+  * `getXdgDirectory` will no longer reject environment variables containing
+    relative paths.
+    ([#87](https://github.com/haskell/directory/issues/87))
+
+## 1.3.3.1 (August 2018)
+
+  * `doesDirectoryExist` and `doesPathExist` reject empty paths once again,
+    reversing an undocumented change introduced in 1.3.1.1.
+    ([#84](https://github.com/haskell/directory/issues/84))
+
+## 1.3.3.0 (June 2018)
+
+  * Relax `unix` version bounds to support 2.8.
+
+  * Relax `Win32` version bounds to support 2.8.
+
+  * Use `SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE` when creating symbolic
+    links on Windows, if possible.
+    ([#83](https://github.com/haskell/directory/issues/83))
+
+## 1.3.2.2 (April 2018)
+
+  * Relax `base` version bounds to support 4.12.
+
+## 1.3.2.1 (March 2018)
+
+  * Relax `Win32` version bounds to support 2.7.
+
+## 1.3.2.0 (January 2018)
+
+  * Relax `time` version bounds to support 1.9.
+
+  * Implement `getXdgDirectoryList` and `XdgDirectoryList`.
+    ([#78](https://github.com/haskell/directory/issues/78))
+
+## 1.3.1.5 (October 2017)
+
+  * Rename the internal header `windows.h` to avoid GHC#14312.
+    ([#77](https://github.com/haskell/directory/issues/77))
+
+## 1.3.1.4 (September 2017)
+
+  * Fix `Win32` version 2.6 compatibility.
+    ([#75](https://github.com/haskell/directory/pull/75))
+
+## 1.3.1.3 (September 2017)
+
+  * Relax `Win32` version bounds to support 2.6.
+
+## 1.3.1.2 (September 2017)
+
+  * Relax `base` version bounds to support 4.11.
+    ([#74](https://github.com/haskell/directory/pull/74))
+
+## 1.3.1.1 (March 2017)
+
+  * Fix a bug where `createFileLink` and `createDirectoryLink` failed to
+    handle `..` in absolute paths.
+
+  * Improve support (partially) for paths longer than 260 characters on
+    Windows.  To achieve this, many functions will now automatically prepend
+    `\\?\` before calling the Windows API.  As a side effect, the `\\?\`
+    prefix may show up in the error messages of the affected functions.
+
+  * `makeAbsolute` can now handle drive-relative paths on Windows such as
+    `C:foobar`
+
+## 1.3.1.0 (March 2017)
+
+  * `findFile` (and similar functions): when an absolute path is given, the
+    list of search directories is now completely ignored.  Previously, if the
+    list was empty, `findFile` would always fail.
+    ([#72](https://github.com/haskell/directory/issues/72))
+
+  * For symbolic links on Windows, the following functions had previously
+    interpreted paths as referring to the links themselves rather than their
+    targets.  This was inconsistent with other platforms and has been fixed.
+      * `getFileSize`
+      * `doesPathExist`
+      * `doesDirectoryExist`
+      * `doesFileExist`
+
+  * Fix incorrect location info in errors from `pathIsSymbolicLink`.
+
+  * Add functions for symbolic link manipulation:
+      * `createFileLink`
+      * `createDirectoryLink`
+      * `removeDirectoryLink`
+      * `getSymbolicLinkTarget`
+
+  * `canonicalizePath` can now resolve broken symbolic links too.
+    ([#64](https://github.com/haskell/directory/issues/64))
+
+## 1.3.0.2 (February 2017)
+
+  * [optimization] Increase internal buffer size of `copyFile`
+    ([#69](https://github.com/haskell/directory/pull/69))
+
+  * Relax `time` version bounds to support 1.8.
+
+## 1.3.0.1 (January 2017)
+
+  * Relax `Win32` version bounds to support 2.5.
+    ([#67](https://github.com/haskell/directory/pull/67))
+
 ## 1.3.0.0 (December 2016)
 
-  * Drop trailing slashes in `canonicalizePath`
+  * **[breaking]** Drop trailing slashes in `canonicalizePath`
     ([#63](https://github.com/haskell/directory/issues/63))
 
-  * Rename `isSymbolicLink` to `pathIsSymbolicLink`.  The old name will remain
-    available but may be removed in the next major release.
+  * **[deprecation]** Rename `isSymbolicLink` to `pathIsSymbolicLink`.  The
+    old name will remain available but may be removed in the next major
+    release.
     ([#52](https://github.com/haskell/directory/issues/52))
 
   * Changed `canonicalizePath` to dereference symbolic links even if it points
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -1,4378 +1,4426 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Haskell directory package 1.0.
-#
-# Report bugs to <libraries@haskell.org>.
-#
-#
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
-#
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-  done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Use a proper internal environment variable to ensure we don't fall
-  # into an infinite loop, continuously re-executing ourselves.
-  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
-    _as_can_reexec=no; export _as_can_reexec;
-    # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
-  fi
-  # We don't want this to propagate to other subprocesses.
-          { _as_can_reexec=; unset _as_can_reexec;}
-if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '\${1+\"\$@\"}'='\"\$@\"'
-  setopt NO_GLOB_SUBST
-else
-  case \`(set -o) 2>/dev/null\` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-"
-  as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
-  exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1
-test -x / || exit 1"
-  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
-  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
-  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
-  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
-  if (eval "$as_required") 2>/dev/null; then :
-  as_have_required=yes
-else
-  as_have_required=no
-fi
-  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  as_found=:
-  case $as_dir in #(
-	 /*)
-	   for as_base in sh bash ksh sh5; do
-	     # Try only shells that exist, to save several forks.
-	     as_shell=$as_dir/$as_base
-	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
-  CONFIG_SHELL=$as_shell as_have_required=yes
-		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
-  break 2
-fi
-fi
-	   done;;
-       esac
-  as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
-	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
-  CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
-      if test "x$CONFIG_SHELL" != x; then :
-  export CONFIG_SHELL
-             # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
-fi
-
-    if test x$as_have_required = xno; then :
-  $as_echo "$0: This script requires a shell more modern than all"
-  $as_echo "$0: the shells that I found on your system."
-  if test x${ZSH_VERSION+set} = xset ; then
-    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
-    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
-  else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: libraries@haskell.org about your system, including any
-$0: error possibly output before this message. Then install
-$0: a modern shell, or manually run the script under such a
-$0: shell if you do have one."
-  fi
-  exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
-  { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
-  return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
-  set +e
-  as_fn_set_status $1
-  exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || eval $as_mkdir_p || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
-  eval 'as_fn_append ()
-  {
-    eval $1+=\$2
-  }'
-else
-  as_fn_append ()
-  {
-    eval $1=\$$1\$2
-  }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
-  eval 'as_fn_arith ()
-  {
-    as_val=$(( $* ))
-  }'
-else
-  as_fn_arith ()
-  {
-    as_val=`expr "$@" || test $? -eq 1`
-  }
-fi # as_fn_arith
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
-  fi
-  $as_echo "$as_me: error: $2" >&2
-  as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
-  as_lineno_1=$LINENO as_lineno_1a=$LINENO
-  as_lineno_2=$LINENO as_lineno_2a=$LINENO
-  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
-  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
-  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
-    sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
-      N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
-      t loop
-      s/-\n.*//
-    ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
-  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
-  # already done that, so ensure we don't try to do so again and fall
-  # in an infinite loop.  This has already happened in practice.
-  _as_can_reexec=no; export _as_can_reexec
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
-  # Exit status is that of the last command.
-  exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
-  case `echo 'xy\c'` in
-  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  xy)  ECHO_C='\c';;
-  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
-       ECHO_T='	';;
-  esac;;
-*)
-  ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
-  if ln -s conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s='ln -s'
-    # ... but there are two gotchas:
-    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
-    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
-  elif ln conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s=ln
-  else
-    as_ln_s='cp -pR'
-  fi
-else
-  as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p='mkdir -p "$as_dir"'
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-test -n "$DJDIR" || exec 7<&0 </dev/null
-exec 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME='Haskell directory package'
-PACKAGE_TARNAME='directory'
-PACKAGE_VERSION='1.0'
-PACKAGE_STRING='Haskell directory package 1.0'
-PACKAGE_BUGREPORT='libraries@haskell.org'
-PACKAGE_URL=''
-
-ac_unique_file="System/Directory.hs"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='LTLIBOBJS
-LIBOBJS
-EGREP
-GREP
-CPP
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL'
-ac_subst_files=''
-ac_user_opts='
-enable_option_checking
-with_gcc
-with_compiler
-'
-      ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CPP'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
-  # If the previous option needs an argument, assign it.
-  if test -n "$ac_prev"; then
-    eval $ac_prev=\$ac_option
-    ac_prev=
-    continue
-  fi
-
-  case $ac_option in
-  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *=)   ac_optarg= ;;
-  *)    ac_optarg=yes ;;
-  esac
-
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
-  case $ac_dashdash$ac_option in
-  --)
-    ac_dashdash=yes ;;
-
-  -bindir | --bindir | --bindi | --bind | --bin | --bi)
-    ac_prev=bindir ;;
-  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-    bindir=$ac_optarg ;;
-
-  -build | --build | --buil | --bui | --bu)
-    ac_prev=build_alias ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-    build_alias=$ac_optarg ;;
-
-  -cache-file | --cache-file | --cache-fil | --cache-fi \
-  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-    ac_prev=cache_file ;;
-  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-    cache_file=$ac_optarg ;;
-
-  --config-cache | -C)
-    cache_file=config.cache ;;
-
-  -datadir | --datadir | --datadi | --datad)
-    ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=*)
-    datadir=$ac_optarg ;;
-
-  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
-  | --dataroo | --dataro | --datar)
-    ac_prev=datarootdir ;;
-  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
-  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
-    datarootdir=$ac_optarg ;;
-
-  -disable-* | --disable-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"enable_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval enable_$ac_useropt=no ;;
-
-  -docdir | --docdir | --docdi | --doc | --do)
-    ac_prev=docdir ;;
-  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
-    docdir=$ac_optarg ;;
-
-  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
-    ac_prev=dvidir ;;
-  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
-    dvidir=$ac_optarg ;;
-
-  -enable-* | --enable-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"enable_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval enable_$ac_useropt=\$ac_optarg ;;
-
-  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-  | --exec | --exe | --ex)
-    ac_prev=exec_prefix ;;
-  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-  | --exec=* | --exe=* | --ex=*)
-    exec_prefix=$ac_optarg ;;
-
-  -gas | --gas | --ga | --g)
-    # Obsolete; use --with-gas.
-    with_gas=yes ;;
-
-  -help | --help | --hel | --he | -h)
-    ac_init_help=long ;;
-  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
-    ac_init_help=recursive ;;
-  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
-    ac_init_help=short ;;
-
-  -host | --host | --hos | --ho)
-    ac_prev=host_alias ;;
-  -host=* | --host=* | --hos=* | --ho=*)
-    host_alias=$ac_optarg ;;
-
-  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
-    ac_prev=htmldir ;;
-  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
-  | --ht=*)
-    htmldir=$ac_optarg ;;
-
-  -includedir | --includedir | --includedi | --included | --include \
-  | --includ | --inclu | --incl | --inc)
-    ac_prev=includedir ;;
-  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-  | --includ=* | --inclu=* | --incl=* | --inc=*)
-    includedir=$ac_optarg ;;
-
-  -infodir | --infodir | --infodi | --infod | --info | --inf)
-    ac_prev=infodir ;;
-  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-    infodir=$ac_optarg ;;
-
-  -libdir | --libdir | --libdi | --libd)
-    ac_prev=libdir ;;
-  -libdir=* | --libdir=* | --libdi=* | --libd=*)
-    libdir=$ac_optarg ;;
-
-  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-  | --libexe | --libex | --libe)
-    ac_prev=libexecdir ;;
-  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-  | --libexe=* | --libex=* | --libe=*)
-    libexecdir=$ac_optarg ;;
-
-  -localedir | --localedir | --localedi | --localed | --locale)
-    ac_prev=localedir ;;
-  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
-    localedir=$ac_optarg ;;
-
-  -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst | --locals)
-    ac_prev=localstatedir ;;
-  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
-    localstatedir=$ac_optarg ;;
-
-  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-    ac_prev=mandir ;;
-  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-    mandir=$ac_optarg ;;
-
-  -nfp | --nfp | --nf)
-    # Obsolete; use --without-fp.
-    with_fp=no ;;
-
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c | -n)
-    no_create=yes ;;
-
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    no_recursion=yes ;;
-
-  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-  | --oldin | --oldi | --old | --ol | --o)
-    ac_prev=oldincludedir ;;
-  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-    oldincludedir=$ac_optarg ;;
-
-  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-    ac_prev=prefix ;;
-  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-    prefix=$ac_optarg ;;
-
-  -program-prefix | --program-prefix | --program-prefi | --program-pref \
-  | --program-pre | --program-pr | --program-p)
-    ac_prev=program_prefix ;;
-  -program-prefix=* | --program-prefix=* | --program-prefi=* \
-  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-    program_prefix=$ac_optarg ;;
-
-  -program-suffix | --program-suffix | --program-suffi | --program-suff \
-  | --program-suf | --program-su | --program-s)
-    ac_prev=program_suffix ;;
-  -program-suffix=* | --program-suffix=* | --program-suffi=* \
-  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-    program_suffix=$ac_optarg ;;
-
-  -program-transform-name | --program-transform-name \
-  | --program-transform-nam | --program-transform-na \
-  | --program-transform-n | --program-transform- \
-  | --program-transform | --program-transfor \
-  | --program-transfo | --program-transf \
-  | --program-trans | --program-tran \
-  | --progr-tra | --program-tr | --program-t)
-    ac_prev=program_transform_name ;;
-  -program-transform-name=* | --program-transform-name=* \
-  | --program-transform-nam=* | --program-transform-na=* \
-  | --program-transform-n=* | --program-transform-=* \
-  | --program-transform=* | --program-transfor=* \
-  | --program-transfo=* | --program-transf=* \
-  | --program-trans=* | --program-tran=* \
-  | --progr-tra=* | --program-tr=* | --program-t=*)
-    program_transform_name=$ac_optarg ;;
-
-  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
-    ac_prev=pdfdir ;;
-  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
-    pdfdir=$ac_optarg ;;
-
-  -psdir | --psdir | --psdi | --psd | --ps)
-    ac_prev=psdir ;;
-  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
-    psdir=$ac_optarg ;;
-
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil)
-    silent=yes ;;
-
-  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-    ac_prev=sbindir ;;
-  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-  | --sbi=* | --sb=*)
-    sbindir=$ac_optarg ;;
-
-  -sharedstatedir | --sharedstatedir | --sharedstatedi \
-  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-  | --sharedst | --shareds | --shared | --share | --shar \
-  | --sha | --sh)
-    ac_prev=sharedstatedir ;;
-  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-  | --sha=* | --sh=*)
-    sharedstatedir=$ac_optarg ;;
-
-  -site | --site | --sit)
-    ac_prev=site ;;
-  -site=* | --site=* | --sit=*)
-    site=$ac_optarg ;;
-
-  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-    ac_prev=srcdir ;;
-  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-    srcdir=$ac_optarg ;;
-
-  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-  | --syscon | --sysco | --sysc | --sys | --sy)
-    ac_prev=sysconfdir ;;
-  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-    sysconfdir=$ac_optarg ;;
-
-  -target | --target | --targe | --targ | --tar | --ta | --t)
-    ac_prev=target_alias ;;
-  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-    target_alias=$ac_optarg ;;
-
-  -v | -verbose | --verbose | --verbos | --verbo | --verb)
-    verbose=yes ;;
-
-  -version | --version | --versio | --versi | --vers | -V)
-    ac_init_version=: ;;
-
-  -with-* | --with-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"with_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval with_$ac_useropt=\$ac_optarg ;;
-
-  -without-* | --without-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"with_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval with_$ac_useropt=no ;;
-
-  --x)
-    # Obsolete; use --with-x.
-    with_x=yes ;;
-
-  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-  | --x-incl | --x-inc | --x-in | --x-i)
-    ac_prev=x_includes ;;
-  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-    x_includes=$ac_optarg ;;
-
-  -x-libraries | --x-libraries | --x-librarie | --x-librari \
-  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-    ac_prev=x_libraries ;;
-  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-    x_libraries=$ac_optarg ;;
-
-  -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
-    ;;
-
-  *=*)
-    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
-    # Reject names that are not valid shell variable names.
-    case $ac_envvar in #(
-      '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
-    esac
-    eval $ac_envvar=\$ac_optarg
-    export $ac_envvar ;;
-
-  *)
-    # FIXME: should be removed in autoconf 3.0.
-    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
-    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
-    ;;
-
-  esac
-done
-
-if test -n "$ac_prev"; then
-  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error $? "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
-  case $enable_option_checking in
-    no) ;;
-    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
-    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
-  esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
-		datadir sysconfdir sharedstatedir localstatedir includedir \
-		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
-do
-  eval ac_val=\$$ac_var
-  # Remove trailing slashes.
-  case $ac_val in
-    */ )
-      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
-      eval $ac_var=\$ac_val;;
-  esac
-  # Be sure to have absolute directory names.
-  case $ac_val in
-    [\\/$]* | ?:[\\/]* )  continue;;
-    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
-  esac
-  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
-  if test "x$build_alias" = x; then
-    cross_compiling=maybe
-  elif test "x$build_alias" != "x$host_alias"; then
-    cross_compiling=yes
-  fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error $? "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error $? "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
-  ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_myself" : 'X\(//\)[^/]' \| \
-	 X"$as_myself" : 'X\(//\)$' \| \
-	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  srcdir=$ac_confdir
-  if test ! -r "$srcdir/$ac_unique_file"; then
-    srcdir=..
-  fi
-else
-  ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
-  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
-	pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
-  srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
-  eval ac_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_env_${ac_var}_value=\$${ac_var}
-  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
-  # Omit some internal or obsolete options to make the list less imposing.
-  # This message is too long to be a string in the A/UX 3.1 sh.
-  cat <<_ACEOF
-\`configure' configures Haskell directory package 1.0 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE.  See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
-  -h, --help              display this help and exit
-      --help=short        display options specific to this package
-      --help=recursive    display the short help of all the included packages
-  -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking ...' messages
-      --cache-file=FILE   cache test results in FILE [disabled]
-  -C, --config-cache      alias for \`--cache-file=config.cache'
-  -n, --no-create         do not create output files
-      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
-
-Installation directories:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [$ac_default_prefix]
-  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-                          [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
-  --bindir=DIR            user executables [EPREFIX/bin]
-  --sbindir=DIR           system admin executables [EPREFIX/sbin]
-  --libexecdir=DIR        program executables [EPREFIX/libexec]
-  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
-  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
-  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --libdir=DIR            object code libraries [EPREFIX/lib]
-  --includedir=DIR        C header files [PREFIX/include]
-  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
-  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR           info documentation [DATAROOTDIR/info]
-  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR            man documentation [DATAROOTDIR/man]
-  --docdir=DIR            documentation root [DATAROOTDIR/doc/directory]
-  --htmldir=DIR           html documentation [DOCDIR]
-  --dvidir=DIR            dvi documentation [DOCDIR]
-  --pdfdir=DIR            pdf documentation [DOCDIR]
-  --psdir=DIR             ps documentation [DOCDIR]
-_ACEOF
-
-  cat <<\_ACEOF
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-  case $ac_init_help in
-     short | recursive ) echo "Configuration of Haskell directory package 1.0:";;
-   esac
-  cat <<\_ACEOF
-
-Optional Packages:
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-C compiler
-GHC compiler
-
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
-              you have headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <libraries@haskell.org>.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
-  # If there are subdirs, report their specific --help.
-  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" ||
-      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
-      continue
-    ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
-  .)  # We are building in place.
-    ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-    cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
-    if test -f "$ac_srcdir/configure.gnu"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
-    elif test -f "$ac_srcdir/configure"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure" --help=recursive
-    else
-      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi || ac_status=$?
-    cd "$ac_pwd" || { ac_status=$?; break; }
-  done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
-  cat <<\_ACEOF
-Haskell directory package configure 1.0
-generated by GNU Autoconf 2.69
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
-  exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
-  if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-    ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------ ##
-## Report this to libraries@haskell.org ##
-## ------------------------------------ ##"
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_compile
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-	 test "$cross_compiling" = yes ||
-	 test -x conftest$ac_exeext
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_retval=1
-fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by Haskell directory package $as_me 1.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
-
-  $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
-
-/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
-/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
-/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    $as_echo "PATH: $as_dir"
-  done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
-  for ac_arg
-  do
-    case $ac_arg in
-    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
-    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-    | -silent | --silent | --silen | --sile | --sil)
-      continue ;;
-    *\'*)
-      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    case $ac_pass in
-    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
-    2)
-      as_fn_append ac_configure_args1 " '$ac_arg'"
-      if test $ac_must_keep_next = true; then
-	ac_must_keep_next=false # Got value, back to normal.
-      else
-	case $ac_arg in
-	  *=* | --config-cache | -C | -disable-* | --disable-* \
-	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
-	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
-	  | -with-* | --with-* | -without-* | --without-* | --x)
-	    case "$ac_configure_args0 " in
-	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
-	    esac
-	    ;;
-	  -* ) ac_must_keep_next=true ;;
-	esac
-      fi
-      as_fn_append ac_configure_args " '$ac_arg'"
-      ;;
-    esac
-  done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log.  We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
-  # Save into config.log some information that might help in debugging.
-  {
-    echo
-
-    $as_echo "## ---------------- ##
-## Cache variables. ##
-## ---------------- ##"
-    echo
-    # The following way of writing the cache mishandles newlines in values,
-(
-  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
-      *) { eval $ac_var=; unset $ac_var;} ;;
-      esac ;;
-    esac
-  done
-  (set) 2>&1 |
-    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      sed -n \
-	"s/'\''/'\''\\\\'\'''\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
-      ;; #(
-    *)
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-)
-    echo
-
-    $as_echo "## ----------------- ##
-## Output variables. ##
-## ----------------- ##"
-    echo
-    for ac_var in $ac_subst_vars
-    do
-      eval ac_val=\$$ac_var
-      case $ac_val in
-      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-      esac
-      $as_echo "$ac_var='\''$ac_val'\''"
-    done | sort
-    echo
-
-    if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
-## File substitutions. ##
-## ------------------- ##"
-      echo
-      for ac_var in $ac_subst_files
-      do
-	eval ac_val=\$$ac_var
-	case $ac_val in
-	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-	esac
-	$as_echo "$ac_var='\''$ac_val'\''"
-      done | sort
-      echo
-    fi
-
-    if test -s confdefs.h; then
-      $as_echo "## ----------- ##
-## confdefs.h. ##
-## ----------- ##"
-      echo
-      cat confdefs.h
-      echo
-    fi
-    test "$ac_signal" != 0 &&
-      $as_echo "$as_me: caught signal $ac_signal"
-    $as_echo "$as_me: exit $exit_status"
-  } >&5
-  rm -f core *.core core.conftest.* &&
-    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
-    exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
-  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
-elif test "x$prefix" != xNONE; then
-  ac_site_file1=$prefix/share/config.site
-  ac_site_file2=$prefix/etc/config.site
-else
-  ac_site_file1=$ac_default_prefix/share/config.site
-  ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
-  test "x$ac_site_file" = xNONE && continue
-  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
-    sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
-  fi
-done
-
-if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special files
-  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
-  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
-    case $cache_file in
-      [\\/]* | ?:[\\/]* ) . "$cache_file";;
-      *)                      . "./$cache_file";;
-    esac
-  fi
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
-  >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
-  eval ac_old_set=\$ac_cv_env_${ac_var}_set
-  eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
-  case $ac_old_set,$ac_new_set in
-    set,)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,set)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,);;
-    *)
-      if test "x$ac_old_val" != "x$ac_new_val"; then
-	# differences in whitespace do not lead to failure.
-	ac_old_val_w=`echo x $ac_old_val`
-	ac_new_val_w=`echo x $ac_new_val`
-	if test "$ac_old_val_w" != "$ac_new_val_w"; then
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-	  ac_cache_corrupted=:
-	else
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
-	  eval $ac_var=\$ac_old_val
-	fi
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
-$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
-$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
-      fi;;
-  esac
-  # Pass precious variables to config.status.
-  if test "$ac_new_set" = set; then
-    case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
-    *) ac_arg=$ac_var=$ac_new_val ;;
-    esac
-    case " $ac_configure_args " in
-      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
-    esac
-  fi
-done
-if $ac_cache_corrupted; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-# Safety check: Ensure that we are in the correct source directory.
-
-
-ac_config_headers="$ac_config_headers HsDirectoryConfig.h"
-
-
-# Autoconf chokes on spaces, but we may receive a path from Cabal containing
-# spaces.  In that case, we just ignore Cabal's suggestion.
-set_with_gcc() {
-    case $withval in
-        *" "*)
-            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-gcc ignored due to presence of spaces" >&5
-$as_echo "$as_me: WARNING: --with-gcc ignored due to presence of spaces" >&2;};;
-        *)
-            CC=$withval
-    esac
-}
-
-# Legacy support for setting the C compiler with Cabal<1.24
-# Newer versions use Autoconf's native `CC=...` facility
-
-# Check whether --with-gcc was given.
-if test "${with_gcc+set}" = set; then :
-  withval=$with_gcc; set_with_gcc
-fi
-
-# avoid warnings when run via Cabal
-
-# Check whether --with-compiler was given.
-if test "${with_compiler+set}" = set; then :
-  withval=$with_compiler;
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link_default") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
-	;;
-    [ab].out )
-	# We found the default executable, but exeext='' is most
-	# certainly right.
-	break;;
-    *.* )
-	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-	then :; else
-	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	fi
-	# We set ac_cv_exeext here because the later test for it is not
-	# safe: cross compilers may not add the suffix if given an `-o'
-	# argument, so we may need to know it at that point already.
-	# Even if this section looks crufty: it has the advantage of
-	# actually working.
-	break;;
-    * )
-	break;;
-  esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
-  ac_file=''
-fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	  break;;
-    * ) break;;
-  esac
-done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
-  { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-  if { ac_try='./conftest$ac_cv_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
-    fi
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-else
-  CFLAGS=""
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  ac_c_werror_flag=$ac_save_c_werror_flag
-	 CFLAGS="-g"
-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# check for specific header (.h) files that we are interested in
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     if test -z "$EGREP"; then
-  ac_path_EGREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_EGREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_EGREP=$EGREP
-fi
-
-   fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-		  inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in fcntl.h limits.h sys/types.h sys/stat.h time.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_func in utimensat
-do :
-  ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"
-if test "x$ac_cv_func_utimensat" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_UTIMENSAT 1
-_ACEOF
-
-fi
-done
-
-for ac_func in GetFinalPathNameByHandleW
-do :
-  ac_fn_c_check_func "$LINENO" "GetFinalPathNameByHandleW" "ac_cv_func_GetFinalPathNameByHandleW"
-if test "x$ac_cv_func_GetFinalPathNameByHandleW" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_GETFINALPATHNAMEBYHANDLEW 1
-_ACEOF
-
-fi
-done
-
-
-# EXTEXT is defined automatically by AC_PROG_CC;
-# we just need to capture it in the header file
-
-cat >>confdefs.h <<_ACEOF
-#define EXE_EXTENSION "$EXEEXT"
-_ACEOF
-
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems.  If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
-  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
-      *) { eval $ac_var=; unset $ac_var;} ;;
-      esac ;;
-    esac
-  done
-
-  (set) 2>&1 |
-    case $as_nl`(ac_space=' '; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      # `set' does not quote correctly, so add quotes: double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \.
-      sed -n \
-	"s/'/'\\\\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;; #(
-    *)
-      # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-) |
-  sed '
-     /^ac_cv_env_/b end
-     t clear
-     :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
-     t end
-     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
-  if test -w "$cache_file"; then
-    if test "x$cache_file" != "x/dev/null"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
-      if test ! -f "$cache_file" || test -h "$cache_file"; then
-	cat confcache >"$cache_file"
-      else
-        case $cache_file in #(
-        */* | ?:*)
-	  mv -f confcache "$cache_file"$$ &&
-	  mv -f "$cache_file"$$ "$cache_file" ;; #(
-        *)
-	  mv -f confcache "$cache_file" ;;
-	esac
-      fi
-    fi
-  else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
-  fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-U=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
-  # 1. Remove the extension, and $U if already installed.
-  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
-  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
-  #    will be set to the directory where LIBOBJS objects are built.
-  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: "${CONFIG_STATUS=./config.status}"
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-  done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
-  fi
-  $as_echo "$as_me: error: $2" >&2
-  as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
-  return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
-  set +e
-  as_fn_set_status $1
-  exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
-  { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
-  eval 'as_fn_append ()
-  {
-    eval $1+=\$2
-  }'
-else
-  as_fn_append ()
-  {
-    eval $1=\$$1\$2
-  }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
-  eval 'as_fn_arith ()
-  {
-    as_val=$(( $* ))
-  }'
-else
-  as_fn_arith ()
-  {
-    as_val=`expr "$@" || test $? -eq 1`
-  }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
-  case `echo 'xy\c'` in
-  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  xy)  ECHO_C='\c';;
-  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
-       ECHO_T='	';;
-  esac;;
-*)
-  ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
-  if ln -s conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s='ln -s'
-    # ... but there are two gotchas:
-    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
-    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
-  elif ln conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s=ln
-  else
-    as_ln_s='cp -pR'
-  fi
-else
-  as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || eval $as_mkdir_p || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p='mkdir -p "$as_dir"'
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by Haskell directory package $as_me 1.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
-
-  CONFIG_FILES    = $CONFIG_FILES
-  CONFIG_HEADERS  = $CONFIG_HEADERS
-  CONFIG_LINKS    = $CONFIG_LINKS
-  CONFIG_COMMANDS = $CONFIG_COMMANDS
-  $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-
-case $ac_config_headers in *"
-"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
-esac
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_headers="$ac_config_headers"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration.  Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
-  -h, --help       print this help, then exit
-  -V, --version    print version number and configuration settings, then exit
-      --config     print configuration, then exit
-  -q, --quiet, --silent
-                   do not print progress messages
-  -d, --debug      don't remove temporary files
-      --recheck    update $as_me by reconfiguring in the same conditions
-      --header=FILE[:TEMPLATE]
-                   instantiate the configuration header FILE
-
-Configuration headers:
-$config_headers
-
-Report bugs to <libraries@haskell.org>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
-ac_cs_version="\\
-Haskell directory package config.status 1.0
-configured by $0, generated by GNU Autoconf 2.69,
-  with options \\"\$ac_cs_config\\"
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
-  case $1 in
-  --*=?*)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
-    ac_shift=:
-    ;;
-  --*=)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=
-    ac_shift=:
-    ;;
-  *)
-    ac_option=$1
-    ac_optarg=$2
-    ac_shift=shift
-    ;;
-  esac
-
-  case $ac_option in
-  # Handling of the options.
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    ac_cs_recheck=: ;;
-  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    $as_echo "$ac_cs_version"; exit ;;
-  --config | --confi | --conf | --con | --co | --c )
-    $as_echo "$ac_cs_config"; exit ;;
-  --debug | --debu | --deb | --de | --d | -d )
-    debug=: ;;
-  --header | --heade | --head | --hea )
-    $ac_shift
-    case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
-    ac_need_defaults=false;;
-  --he | --h)
-    # Conflict between --help and --header
-    as_fn_error $? "ambiguous option: \`$1'
-Try \`$0 --help' for more information.";;
-  --help | --hel | -h )
-    $as_echo "$ac_cs_usage"; exit ;;
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil | --si | --s)
-    ac_cs_silent=: ;;
-
-  # This is an error.
-  -*) as_fn_error $? "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
-  *) as_fn_append ac_config_targets " $1"
-     ac_need_defaults=false ;;
-
-  esac
-  shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
-  exec 6>/dev/null
-  ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
-  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-  shift
-  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
-  CONFIG_SHELL='$SHELL'
-  export CONFIG_SHELL
-  exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-  $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
-  case $ac_config_target in
-    "HsDirectoryConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS HsDirectoryConfig.h" ;;
-
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
-  esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used.  Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
-  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-fi
-
-# Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
-  tmp= ac_tmp=
-  trap 'exit_status=$?
-  : "${ac_tmp:=$tmp}"
-  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
-' 0
-  trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
-  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -d "$tmp"
-}  ||
-{
-  tmp=./conf$$-$RANDOM
-  (umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-ac_tmp=$tmp
-
-# Set up the scripts for CONFIG_HEADERS section.
-# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
-if test -n "$CONFIG_HEADERS"; then
-cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
-BEGIN {
-_ACEOF
-
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
-# config.h.in to produce config.h.
-
-# Create a delimiter string that does not exist in confdefs.h, to ease
-# handling of long lines.
-ac_delim='%!_!# '
-for ac_last_try in false false :; do
-  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_tt"; then
-    break
-  elif $ac_last_try; then
-    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
-  else
-    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
-  fi
-done
-
-# For the awk script, D is an array of macro values keyed by name,
-# likewise P contains macro parameters if any.  Preserve backslash
-# newline sequences.
-
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-sed -n '
-s/.\{148\}/&'"$ac_delim"'/g
-t rset
-:rset
-s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
-t def
-d
-:def
-s/\\$//
-t bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3"/p
-s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
-d
-:bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3\\\\\\n"\\/p
-t cont
-s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
-t cont
-d
-:cont
-n
-s/.\{148\}/&'"$ac_delim"'/g
-t clear
-:clear
-s/\\$//
-t bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/"/p
-d
-:bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
-b cont
-' <confdefs.h | sed '
-s/'"$ac_delim"'/"\\\
-"/g' >>$CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-  for (key in D) D_is_set[key] = 1
-  FS = ""
-}
-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
-  line = \$ 0
-  split(line, arg, " ")
-  if (arg[1] == "#") {
-    defundef = arg[2]
-    mac1 = arg[3]
-  } else {
-    defundef = substr(arg[1], 2)
-    mac1 = arg[2]
-  }
-  split(mac1, mac2, "(") #)
-  macro = mac2[1]
-  prefix = substr(line, 1, index(line, defundef) - 1)
-  if (D_is_set[macro]) {
-    # Preserve the white space surrounding the "#".
-    print prefix "define", macro P[macro] D[macro]
-    next
-  } else {
-    # Replace #undef with comments.  This is necessary, for example,
-    # in the case of _POSIX_SOURCE, which is predefined and required
-    # on some systems where configure will not decide to define it.
-    if (defundef == "undef") {
-      print "/*", prefix defundef, macro, "*/"
-      next
-    }
-  }
-}
-{ print }
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
-fi # test -n "$CONFIG_HEADERS"
-
-
-eval set X "    :H $CONFIG_HEADERS    "
-shift
-for ac_tag
-do
-  case $ac_tag in
-  :[FHLC]) ac_mode=$ac_tag; continue;;
-  esac
-  case $ac_mode$ac_tag in
-  :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
-  :[FH]-) ac_tag=-:-;;
-  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
-  esac
-  ac_save_IFS=$IFS
-  IFS=:
-  set x $ac_tag
-  IFS=$ac_save_IFS
-  shift
-  ac_file=$1
-  shift
-
-  case $ac_mode in
-  :L) ac_source=$1;;
-  :[FH])
-    ac_file_inputs=
-    for ac_f
-    do
-      case $ac_f in
-      -) ac_f="$ac_tmp/stdin";;
-      *) # Look for the file first in the build tree, then in the source tree
-	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
-	 # because $ac_f cannot contain `:'.
-	 test -f "$ac_f" ||
-	   case $ac_f in
-	   [\\/$]*) false;;
-	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
-	   esac ||
-	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
-      esac
-      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
-      as_fn_append ac_file_inputs " '$ac_f'"
-    done
-
-    # Let's still pretend it is `configure' which instantiates (i.e., don't
-    # use $as_me), people would be surprised to read:
-    #    /* config.h.  Generated by config.status.  */
-    configure_input='Generated from '`
-	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
-	`' by configure.'
-    if test x"$ac_file" != x-; then
-      configure_input="$ac_file.  $configure_input"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
-    fi
-    # Neutralize special characters interpreted by sed in replacement strings.
-    case $configure_input in #(
-    *\&* | *\|* | *\\* )
-       ac_sed_conf_input=`$as_echo "$configure_input" |
-       sed 's/[\\\\&|]/\\\\&/g'`;; #(
-    *) ac_sed_conf_input=$configure_input;;
-    esac
-
-    case $ac_tag in
-    *:-:* | *:-) cat >"$ac_tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
-    esac
-    ;;
-  esac
-
-  ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$ac_file" : 'X\(//\)[^/]' \| \
-	 X"$ac_file" : 'X\(//\)$' \| \
-	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  as_dir="$ac_dir"; as_fn_mkdir_p
-  ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
-  .)  # We are building in place.
-    ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
-  case $ac_mode in
-
-  :H)
-  #
-  # CONFIG_HEADER
-  #
-  if test x"$ac_file" != x-; then
-    {
-      $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
-    } >"$ac_tmp/config.h" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
-    else
-      rm -f "$ac_file"
-      mv "$ac_tmp/config.h" "$ac_file" \
-	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    fi
-  else
-    $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
-      || as_fn_error $? "could not create -" "$LINENO" 5
-  fi
- ;;
-
-
-  esac
-
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
-  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded.  So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status.  When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
-  ac_cs_success=:
-  ac_config_status_args=
-  test "$silent" = yes &&
-    ac_config_status_args="$ac_config_status_args --quiet"
-  exec 5>/dev/null
-  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
-  exec 5>>config.log
-  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
-  # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit 1
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
+# Generated by GNU Autoconf 2.71 for Haskell directory package 1.0.
+#
+# Report bugs to <libraries@haskell.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
+# Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else $as_nop
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else \$as_nop
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
+
+else \$as_nop
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+  if (eval "$as_required") 2>/dev/null
+then :
+  as_have_required=yes
+else $as_nop
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
+
+else $as_nop
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi
+fi
+
+
+      if test "x$CONFIG_SHELL" != x
+then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno
+then :
+  printf "%s\n" "$0: This script requires a shell more modern than all"
+  printf "%s\n" "$0: the shells that I found on your system."
+  if test ${ZSH_VERSION+y} ; then
+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and
+$0: libraries@haskell.org about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else $as_nop
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else $as_nop
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  printf "%s\n" "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Haskell directory package'
+PACKAGE_TARNAME='directory'
+PACKAGE_VERSION='1.0'
+PACKAGE_STRING='Haskell directory package 1.0'
+PACKAGE_BUGREPORT='libraries@haskell.org'
+PACKAGE_URL=''
+
+ac_unique_file="System/Directory.hs"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_header_c_list=
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_gcc
+with_compiler
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir runstatedir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Haskell directory package 1.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/directory]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Haskell directory package 1.0:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+C compiler
+GHC compiler
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <libraries@haskell.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Haskell directory package configure 1.0
+generated by GNU Autoconf 2.71
+
+Copyright (C) 2021 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest.beam
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+   which can conflict with char $2 (); below.  */
+
+#include <limits.h>
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main (void)
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+ac_configure_args_raw=
+for ac_arg
+do
+  case $ac_arg in
+  *\'*)
+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+  *$as_nl*)
+    ac_safe_unquote= ;;
+  *)
+    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
+    ac_unsafe_a="$ac_unsafe_z#~"
+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Haskell directory package $as_me 1.0, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
+
+  $ $0$ac_configure_args_raw
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    printf "%s\n" "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Sanitize IFS.
+  IFS=" ""	$as_nl"
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    printf "%s\n" "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    printf "%s\n" "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      printf "%s\n" "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      printf "%s\n" "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	printf "%s\n" "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      printf "%s\n" "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      printf "%s\n" "$as_me: caught signal $ac_signal"
+    printf "%s\n" "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+printf "%s\n" "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  ac_site_files="$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
+else
+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+fi
+
+for ac_site_file in $ac_site_files
+do
+  case $ac_site_file in #(
+  */*) :
+     ;; #(
+  *) :
+    ac_site_file=./$ac_site_file ;;
+esac
+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+   Do not test the value of __STDC__, because some compilers set it to 0
+   while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not \xHH hex character constants.
+   These do not provoke an error unfortunately, instead are silently treated
+   as an "x".  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
+   array size at least.  It is necessary to write \x00 == 0 to get something
+   that is true only with -std.  */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+               int, int);'
+
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
+
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+// Does the compiler advertise C99 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
+
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+  #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str = "";
+  int number = 0;
+  float fnumber = 0;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case '\''s'\'': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case '\''d'\'': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case '\''f'\'': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+
+  return *str && number && fnumber;
+}
+'
+
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+  // Check bool.
+  _Bool success = false;
+  success |= (argc != 0);
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[0] = argv[0][0];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+	 || dynamic_array[ni.number - 1] != 543);
+'
+
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+// Does the compiler advertise C11 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
+
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+  int_alignment = _Alignof (int),
+  int_array_alignment = _Alignof (int[100]),
+  char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+  int x;
+  _Static_assert (sizeof (int) <= sizeof (long int),
+                  "_Static_assert does not work in struct");
+  long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+  union {
+    struct { int i; int j; };
+    struct { int k; long int l; } w;
+  };
+  int m;
+} v1;
+'
+
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+  _Static_assert ((offsetof (struct anonymous, i)
+		   == offsetof (struct anonymous, w.k)),
+		  "Anonymous union alignment botch");
+  v1.i = 2;
+  v1.w.k = 5;
+  ok |= v1.i != 5;
+'
+
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  ${ac_c_conftest_c11_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  return ok;
+}
+"
+
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
+	    and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Safety check: Ensure that we are in the correct source directory.
+
+
+ac_config_headers="$ac_config_headers HsDirectoryConfig.h"
+
+
+# Autoconf chokes on spaces, but we may receive a path from Cabal containing
+# spaces.  In that case, we just ignore Cabal's suggestion.
+set_with_gcc() {
+    case $withval in
+        *" "*)
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --with-gcc ignored due to presence of spaces" >&5
+printf "%s\n" "$as_me: WARNING: --with-gcc ignored due to presence of spaces" >&2;};;
+        *)
+            CC=$withval
+    esac
+}
+
+# Legacy support for setting the C compiler with Cabal<1.24
+# Newer versions use Autoconf's native `CC=...` facility
+
+# Check whether --with-gcc was given.
+if test ${with_gcc+y}
+then :
+  withval=$with_gcc; set_with_gcc
+fi
+
+# avoid warnings when run via Cabal
+
+# Check whether --with-compiler was given.
+if test ${with_compiler+y}
+then :
+  withval=$with_compiler;
+fi
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+
+
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion -version; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else $as_nop
+  ac_file=''
+fi
+if test -z "$ac_file"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main (void)
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_compiler_gnu=yes
+else $as_nop
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+y}
+ac_save_CFLAGS=$CFLAGS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+else $as_nop
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c11_program
+_ACEOF
+for ac_arg in '' -std=gnu11
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c89_program
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# check for specific header (.h) files that we are interested in
+
+ac_header= ac_cache=
+for ac_item in $ac_header_c_list
+do
+  if test $ac_cache; then
+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+      printf "%s\n" "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_header= ac_cache=
+  elif test $ac_header; then
+    ac_cache=$ac_item
+  else
+    ac_header=$ac_item
+  fi
+done
+
+
+
+
+
+
+
+
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
+
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_fcntl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIMITS_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_types_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_TYPES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stat_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_STAT_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_time_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath"
+if test "x$ac_cv_func_realpath" = xyes
+then :
+  printf "%s\n" "#define HAVE_REALPATH 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"
+if test "x$ac_cv_func_utimensat" = xyes
+then :
+  printf "%s\n" "#define HAVE_UTIMENSAT 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "CreateSymbolicLinkW" "ac_cv_func_CreateSymbolicLinkW"
+if test "x$ac_cv_func_CreateSymbolicLinkW" = xyes
+then :
+  printf "%s\n" "#define HAVE_CREATESYMBOLICLINKW 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "GetFinalPathNameByHandleW" "ac_cv_func_GetFinalPathNameByHandleW"
+if test "x$ac_cv_func_GetFinalPathNameByHandleW" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETFINALPATHNAMEBYHANDLEW 1" >>confdefs.h
+
+fi
+
+
+# EXTEXT is defined automatically by AC_PROG_CC;
+# we just need to capture it in the header file
+
+printf "%s\n" "#define EXE_EXTENSION \"$EXEEXT\"" >>confdefs.h
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else $as_nop
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  printf "%s\n" "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else $as_nop
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else $as_nop
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Haskell directory package $as_me 1.0, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration headers:
+$config_headers
+
+Report bugs to <libraries@haskell.org>."
+
+_ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config='$ac_cs_config_escaped'
+ac_cs_version="\\
+Haskell directory package config.status 1.0
+configured by $0, generated by GNU Autoconf 2.71,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2021 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    printf "%s\n" "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    printf "%s\n" "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    printf "%s\n" "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  printf "%s\n" "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "HsDirectoryConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS HsDirectoryConfig.h" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "    :H $CONFIG_HEADERS    "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      printf "%s\n" "/* $configure_input  */" >&1 \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    printf "%s\n" "/* $configure_input  */" >&1 \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+ ;;
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,9 @@
 # check for specific header (.h) files that we are interested in
 AC_CHECK_HEADERS([fcntl.h limits.h sys/types.h sys/stat.h time.h])
 
+AC_CHECK_FUNCS([realpath])
 AC_CHECK_FUNCS([utimensat])
+AC_CHECK_FUNCS([CreateSymbolicLinkW])
 AC_CHECK_FUNCS([GetFinalPathNameByHandleW])
 
 # EXTEXT is defined automatically by AC_PROG_CC;
diff --git a/directory.buildinfo b/directory.buildinfo
deleted file mode 100644
--- a/directory.buildinfo
+++ /dev/null
@@ -1,1 +0,0 @@
-install-includes: HsDirectoryConfig.h
diff --git a/directory.cabal b/directory.cabal
--- a/directory.cabal
+++ b/directory.cabal
@@ -1,7 +1,7 @@
+cabal-version:  2.2
 name:           directory
-version:        1.3.0.0
--- NOTE: Don't forget to update ./changelog.md
-license:        BSD3
+version:        1.3.11.0
+license:        BSD-3-Clause
 license-file:   LICENSE
 maintainer:     libraries@haskell.org
 bug-reports:    https://github.com/haskell/directory/issues
@@ -11,8 +11,7 @@
   directories in a portable way.
 category:       System
 build-type:     Configure
-cabal-version:  >= 1.10
-tested-with:    GHC>=7.4.1
+tested-with:    GHC == 8.10.7 || == 9.0.2 || == 9.2.4 || == 9.4.3
 
 extra-tmp-files:
     autom4te.cache
@@ -20,16 +19,16 @@
     config.status
     HsDirectoryConfig.h
 
+extra-doc-files:
+    README.md
+    changelog.md
+
 extra-source-files:
     HsDirectoryConfig.h.in
-    README.md
     System/Directory/Internal/*.h
-    changelog.md
     configure
     configure.ac
-    directory.buildinfo
     tests/*.hs
-    tests/util.inl
 
 source-repository head
     type:     git
@@ -37,36 +36,43 @@
 
 Library
     default-language: Haskell2010
-    other-extensions:
-        CPP
-        Trustworthy
+    other-extensions: CApiFFI, CPP
 
     exposed-modules:
         System.Directory
+        System.Directory.OsPath
         System.Directory.Internal
         System.Directory.Internal.Prelude
     other-modules:
-        System.Directory.Internal.Config
         System.Directory.Internal.C_utimensat
+        System.Directory.Internal.Common
+        System.Directory.Internal.Config
         System.Directory.Internal.Posix
         System.Directory.Internal.Windows
 
     include-dirs: .
 
     build-depends:
-        base     >= 4.5 && < 4.11,
-        time     >= 1.4 && < 1.8,
-        filepath >= 1.3 && < 1.5
+        base     >= 4.13.0 && < 4.23,
+        file-io  >= 0.1.4 && < 0.3,
+        time     >= 1.8.0 && < 1.17,
     if os(windows)
-        build-depends: Win32 >= 2.2.2 && < 2.5
+        build-depends: Win32 >= 2.14.1.0 && < 2.15
     else
-        build-depends: unix >= 2.5.1 && < 2.8
+        build-depends: unix >= 2.8.0 && < 2.9
 
+    if impl(ghc >= 9.2)
+      build-depends: filepath >= 1.5.0 && < 1.6,
+                     os-string >= 2.0.0 && < 2.1,
+    else
+      build-depends: filepath >= 1.4.100 && < 1.5
+
     ghc-options: -Wall
 
 test-suite test
     default-language: Haskell2010
     other-extensions: BangPatterns, CPP
+    default-extensions: OverloadedStrings
     ghc-options:      -Wall
     hs-source-dirs:   tests
     main-is:          Main.hs
@@ -91,20 +97,25 @@
         DoesDirectoryExist001
         DoesPathExist
         FileTime
+        FindExecutable
         FindFile001
         GetDirContents001
         GetDirContents002
         GetFileSize
         GetHomeDirectory001
+        GetHomeDirectory002
         GetPermissions001
+        LongPaths
         MakeAbsolute
+        MinimizeNameConflicts
         PathIsSymbolicLink
         RemoveDirectoryRecursive001
         RemovePathForcibly
         RenameDirectory
         RenameFile001
         RenamePath
-        Safe
+        Simplify
         T8482
         WithCurrentDirectory
+        Xdg
         -- test-modules-end
diff --git a/tests/CanonicalizePath.hs b/tests/CanonicalizePath.hs
--- a/tests/CanonicalizePath.hs
+++ b/tests/CanonicalizePath.hs
@@ -1,13 +1,14 @@
 {-# LANGUAGE CPP #-}
 module CanonicalizePath where
-#include "util.inl"
-import System.FilePath ((</>), dropFileName, dropTrailingPathSeparator,
-                        normalise, takeFileName)
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
 import TestUtils
-#ifdef mingw32_HOST_OS
-import System.Directory.Internal (win32_getFinalPathNameByHandle)
-import qualified System.Win32 as Win32
-#endif
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath ((</>), dropFileName, dropTrailingPathSeparator,
+                      normalise, takeFileName)
 
 main :: TestEnv -> IO ()
 main _t = do
@@ -15,10 +16,10 @@
   dot2 <- canonicalizePath "."
   dot3 <- canonicalizePath "./"
   dot4 <- canonicalizePath "./."
-  T(expectEq) () dot (dropTrailingPathSeparator dot)
-  T(expectEq) () dot dot2
-  T(expectEq) () dot dot3
-  T(expectEq) () dot dot4
+  T.expectEq _t () dot (dropTrailingPathSeparator dot)
+  T.expectEq _t () dot dot2
+  T.expectEq _t () dot dot3
+  T.expectEq _t () dot dot4
 
   writeFile "bar" ""
   bar <- canonicalizePath "bar"
@@ -28,13 +29,13 @@
   bar5 <- canonicalizePath "./bar"
   bar6 <- canonicalizePath "./bar/"
   bar7 <- canonicalizePath "./bar/."
-  T(expectEq) () bar (normalise (dot </> "bar"))
-  T(expectEq) () bar bar2
-  T(expectEq) () bar bar3
-  T(expectEq) () bar bar4
-  T(expectEq) () bar bar5
-  T(expectEq) () bar bar6
-  T(expectEq) () bar bar7
+  T.expectEq _t () bar (normalise (dot </> "bar"))
+  T.expectEq _t () bar bar2
+  T.expectEq _t () bar bar3
+  T.expectEq _t () bar bar4
+  T.expectEq _t () bar bar5
+  T.expectEq _t () bar bar6
+  T.expectEq _t () bar bar7
 
   createDirectory "foo"
   foo <- canonicalizePath "foo"
@@ -43,12 +44,12 @@
   foo4 <- canonicalizePath "foo/./"
   foo5 <- canonicalizePath "./foo"
   foo6 <- canonicalizePath "./foo/"
-  T(expectEq) () foo (normalise (dot </> "foo"))
-  T(expectEq) () foo foo2
-  T(expectEq) () foo foo3
-  T(expectEq) () foo foo4
-  T(expectEq) () foo foo5
-  T(expectEq) () foo foo6
+  T.expectEq _t () foo (normalise (dot </> "foo"))
+  T.expectEq _t () foo foo2
+  T.expectEq _t () foo foo3
+  T.expectEq _t () foo foo4
+  T.expectEq _t () foo foo5
+  T.expectEq _t () foo foo6
 
   -- should not fail for non-existent paths
   fooNon <- canonicalizePath "foo/non-existent"
@@ -59,57 +60,63 @@
   fooNon6 <- canonicalizePath "./foo/non-existent/"
   fooNon7 <- canonicalizePath "./foo/./non-existent"
   fooNon8 <- canonicalizePath "./foo/./non-existent/"
-  T(expectEq) () fooNon (normalise (foo </> "non-existent"))
-  T(expectEq) () fooNon fooNon2
-  T(expectEq) () fooNon fooNon3
-  T(expectEq) () fooNon fooNon4
-  T(expectEq) () fooNon fooNon5
-  T(expectEq) () fooNon fooNon6
-  T(expectEq) () fooNon fooNon7
-  T(expectEq) () fooNon fooNon8
-
-  supportsSymbolicLinks <- do
-#ifdef mingw32_HOST_OS
-    hasSymbolicLinkPrivileges <-
-      (True <$ createSymbolicLink "_symlinktest_src" "_symlinktest_dst")
-        -- only test if symbolic links can be created
-        -- (usually disabled on Windows by group policy)
-        `catchIOError` \ e ->
-          if isPermissionError e
-          then pure False
-          else ioError e
-
-    supportsGetFinalPathNameByHandle <-
-      (True <$ win32_getFinalPathNameByHandle Win32.nullHANDLE 0)
-        `catchIOError` \ e ->
-          case ioeGetErrorType e of
-            UnsupportedOperation -> pure False
-            _ -> pure True
+  T.expectEq _t () fooNon (normalise (foo </> "non-existent"))
+  T.expectEq _t () fooNon fooNon2
+  T.expectEq _t () fooNon fooNon3
+  T.expectEq _t () fooNon fooNon4
+  T.expectEq _t () fooNon fooNon5
+  T.expectEq _t () fooNon fooNon6
+  T.expectEq _t () fooNon fooNon7
+  T.expectEq _t () fooNon fooNon8
 
-    pure (hasSymbolicLinkPrivileges && supportsGetFinalPathNameByHandle)
-#else
-    pure True
-#endif
+  -- make sure ".." gets expanded properly by 'toExtendedLengthPath'
+  -- (turns out this test won't detect the problem because GetFullPathName
+  -- would expand them for us if we don't, but leaving it here anyway)
+  T.expectEq _t () foo =<< canonicalizePath (foo </> ".." </> "foo")
 
+  supportsSymbolicLinks <- supportsSymlinks
   when supportsSymbolicLinks $ do
 
     let barQux = dot </> "bar" </> "qux"
 
-    createSymbolicLink "../bar" "foo/bar"
-    T(expectEq) () bar =<< canonicalizePath "foo/bar"
-    T(expectEq) () barQux =<< canonicalizePath "foo/bar/qux"
+    -- note: this also checks that "../bar" gets normalized to "..\\bar"
+    --       since Windows does not like "/" in symbolic links targets
+    createFileLink "../bar" "foo/bar"
+    T.expectEq _t () bar =<< canonicalizePath "foo/bar"
+    T.expectEq _t () barQux =<< canonicalizePath "foo/bar/qux"
 
-    createSymbolicLink "foo" "lfoo"
-    T(expectEq) () foo =<< canonicalizePath "lfoo"
-    T(expectEq) () foo =<< canonicalizePath "lfoo/"
-    T(expectEq) () bar =<< canonicalizePath "lfoo/bar"
-    T(expectEq) () barQux =<< canonicalizePath "lfoo/bar/qux"
+    createDirectoryLink "foo" "lfoo"
+    T.expectEq _t () foo =<< canonicalizePath "lfoo"
+    T.expectEq _t () foo =<< canonicalizePath "lfoo/"
+    T.expectEq _t () bar =<< canonicalizePath "lfoo/bar"
+    T.expectEq _t () barQux =<< canonicalizePath "lfoo/bar/qux"
 
-    -- FIXME: uncomment this test once #64 is fixed
-    -- createSymbolicLink "../foo/non-existent" "foo/qux"
-    -- qux <- canonicalizePath "foo/qux"
-    -- T(expectEq) () qux (dot </> "../foo/non-existent")
+    -- create a haphazard chain of links
+    createDirectoryLink "./../foo/../foo/." "./foo/./somelink3"
+    createDirectoryLink ".././foo/somelink3" "foo/somelink2"
+    createDirectoryLink "./foo/somelink2" "somelink"
+    T.expectEq _t () foo =<< canonicalizePath "somelink"
 
+    -- regression test for #64
+    createFileLink "../foo/non-existent" "foo/qux"
+    removeDirectoryLink "foo/somelink3" -- break the chain made earlier
+    qux <- canonicalizePath "foo/qux"
+    T.expectEq _t () qux =<< canonicalizePath "foo/non-existent"
+    T.expectEq _t () (foo </> "somelink3") =<< canonicalizePath "somelink"
+
+    -- make sure it can handle loops
+    createFileLink "loop1" "loop2"
+    createFileLink "loop2" "loop1"
+    loop1 <- canonicalizePath "loop1"
+    loop2 <- canonicalizePath "loop2"
+    T.expectEq _t () loop1 (normalise (dot </> "loop1"))
+    T.expectEq _t () loop2 (normalise (dot </> "loop2"))
+
+    -- make sure ".." gets expanded properly by 'toExtendedLengthPath'
+    createDirectoryLink (foo </> ".." </> "foo") "foolink"
+    _ <- listDirectory "foolink" -- make sure directory is accessible
+    T.expectEq _t () foo =<< canonicalizePath "foolink"
+
   caseInsensitive <-
     (False <$ createDirectory "FOO")
       `catch` \ e ->
@@ -121,8 +128,8 @@
   when caseInsensitive $ do
     foo7 <- canonicalizePath "FOO"
     foo8 <- canonicalizePath "FOO/"
-    T(expectEq) () foo foo7
-    T(expectEq) () foo foo8
+    T.expectEq _t () foo foo7
+    T.expectEq _t () foo foo8
 
     fooNon9 <- canonicalizePath "FOO/non-existent"
     fooNon10 <- canonicalizePath "fOo/non-existent/"
@@ -132,28 +139,35 @@
     fooNon14 <- canonicalizePath "./FOo/non-existent/"
     cfooNon15 <- canonicalizePath "./FOO/./NON-EXISTENT"
     cfooNon16 <- canonicalizePath "./FOO/./NON-EXISTENT/"
-    T(expectEq) () fooNon fooNon9
-    T(expectEq) () fooNon fooNon10
-    T(expectEq) () fooNon fooNon11
-    T(expectEq) () fooNon fooNon12
-    T(expectEq) () fooNon fooNon13
-    T(expectEq) () fooNon fooNon14
-    T(expectEq) () fooNon (dropFileName cfooNon15 <>
-                           (toLower <$> takeFileName cfooNon15))
-    T(expectEq) () fooNon (dropFileName cfooNon16 <>
-                           (toLower <$> takeFileName cfooNon16))
-    T(expectNe) () fooNon cfooNon15
-    T(expectNe) () fooNon cfooNon16
+    T.expectEq _t () fooNon fooNon9
+    T.expectEq _t () fooNon fooNon10
+    T.expectEq _t () fooNon fooNon11
+    T.expectEq _t () fooNon fooNon12
+    T.expectEq _t () fooNon fooNon13
+    T.expectEq _t () fooNon fooNon14
+    T.expectEq _t () fooNon
+      (dropFileName cfooNon15 <> os (toLower <$> so (takeFileName cfooNon15)))
+    T.expectEq _t () fooNon
+      (dropFileName cfooNon16 <> os (toLower <$> so (takeFileName cfooNon16)))
+    T.expectNe _t () fooNon cfooNon15
+    T.expectNe _t () fooNon cfooNon16
 
     setCurrentDirectory "foo"
     foo9 <- canonicalizePath "../FOO"
     foo10 <- canonicalizePath "../FOO/"
-    T(expectEq) () foo foo9
-    T(expectEq) () foo foo10
+    T.expectEq _t () foo foo9
+    T.expectEq _t () foo foo10
 
-    -- Make sure long file names can be canonicalized too
-    -- (i.e. GetLongPathName by itself won't work)
-    createDirectory "verylongdirectoryname"
-    vldn <- canonicalizePath "verylongdirectoryname"
-    vldn2 <- canonicalizePath "VERYLONGDIRECTORYNAME"
-    T(expectEq) () vldn vldn2
+  let isWindows =
+#if defined(mingw32_HOST_OS)
+        True
+#else
+        False
+#endif
+
+  when isWindows $ do
+    -- https://github.com/haskell/directory/issues/170
+    T.expectEq _t () "\\\\localhost" =<< canonicalizePath "\\\\localhost"
+    -- https://github.com/haskell/directory/issues/206
+    T.expectEq _t () "\\\\localhost\\C$" =<<
+      canonicalizePath "\\\\localhost\\C$\\.."
diff --git a/tests/CopyFile001.hs b/tests/CopyFile001.hs
--- a/tests/CopyFile001.hs
+++ b/tests/CopyFile001.hs
@@ -1,17 +1,29 @@
-{-# LANGUAGE CPP #-}
 module CopyFile001 where
-#include "util.inl"
-import System.FilePath ((</>))
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath ((</>))
 import qualified Data.List as List
 
 main :: TestEnv -> IO ()
 main _t = do
   createDirectory dir
-  writeFile (dir </> from) contents
-  T(expectEq) () [from] . List.sort =<< listDirectory dir
+  writeFile (so (dir </> from)) contents
+  T.expectEq _t () [from] . List.sort =<< listDirectory dir
   copyFile (dir </> from) (dir </> to)
-  T(expectEq) () [from, to] . List.sort =<< listDirectory dir
-  T(expectEq) () contents =<< readFile (dir </> to)
+  T.expectEq _t () [from, to] . List.sort =<< listDirectory dir
+  T.expectEq _t () contents =<< readFile (so (dir </> to))
+
+  -- Regression test for https://github.com/haskell/directory/issues/177
+  createDirectory "issue177"
+  T.expectIOErrorType _t () isDoesNotExistError
+    (copyFile "issue177/nonexistentSrc" "issue177/dst")
+  T.expectEq _t () [] =<< listDirectory "issue177"
+
   where
     contents = "This is the data\n"
     from     = "source"
diff --git a/tests/CopyFile002.hs b/tests/CopyFile002.hs
--- a/tests/CopyFile002.hs
+++ b/tests/CopyFile002.hs
@@ -1,17 +1,22 @@
-{-# LANGUAGE CPP #-}
 module CopyFile002 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 import qualified Data.List as List
 
 main :: TestEnv -> IO ()
 main _t = do
   -- Similar to CopyFile001 but moves a file in the current directory
   -- (Bug #1652 on GHC Trac)
-  writeFile from contents
-  T(expectEq) () [from] . List.sort =<< listDirectory "."
+  writeFile (so from) contents
+  T.expectEq _t () [from] . List.sort =<< listDirectory "."
   copyFile from to
-  T(expectEq) () [from, to] . List.sort =<< listDirectory "."
-  T(expectEq) () contents =<< readFile to
+  T.expectEq _t () [from, to] . List.sort =<< listDirectory "."
+  T.expectEq _t () contents =<< readFile (so to)
   where
     contents = "This is the data\n"
     from     = "source"
diff --git a/tests/CopyFileWithMetadata.hs b/tests/CopyFileWithMetadata.hs
--- a/tests/CopyFileWithMetadata.hs
+++ b/tests/CopyFileWithMetadata.hs
@@ -1,6 +1,11 @@
-{-# LANGUAGE CPP #-}
 module CopyFileWithMetadata where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 import qualified Data.List as List
 
 main :: TestEnv -> IO ()
@@ -14,28 +19,28 @@
   perm <- getPermissions "a"
 
   -- sanity check
-  T(expectEq) () ["a", "b"] . List.sort =<< listDirectory "."
+  T.expectEq _t () ["a", "b"] . List.sort =<< listDirectory "."
 
   -- copy file
   copyFileWithMetadata "a" "b"
   copyFileWithMetadata "a" "c"
 
   -- make sure we got the right results
-  T(expectEq) () ["a", "b", "c"] . List.sort =<< listDirectory "."
+  T.expectEq _t () ["a", "b", "c"] . List.sort =<< listDirectory "."
   for_ ["b", "c"] $ \ f -> do
-    T(expectEq) f perm =<< getPermissions f
-    T(expectEq) f mtime =<< getModificationTime f
-    T(expectEq) f contents =<< readFile f
+    T.expectEq _t f perm =<< getPermissions f
+    T.expectEq _t f mtime =<< getModificationTime f
+    T.expectEq _t f contents =<< readFile (so f)
 
   where
     contents = "This is the data\n"
-    mtime = read "2000-01-01 00:00:00"
+    mtime = read "2000-01-01 00:00:00Z"
 
     cleanup = do
       -- needed to ensure the test runner can clean up our mess
-      modifyWritable True "a" `catchIOError` \ _ -> return ()
-      modifyWritable True "b" `catchIOError` \ _ -> return ()
-      modifyWritable True "c" `catchIOError` \ _ -> return ()
+      modifyWritable True "a" `catchIOError` \ _ -> pure ()
+      modifyWritable True "b" `catchIOError` \ _ -> pure ()
+      modifyWritable True "c" `catchIOError` \ _ -> pure ()
 
     modifyWritable b f = do
       perm <- getPermissions f
diff --git a/tests/CreateDirectory001.hs b/tests/CreateDirectory001.hs
--- a/tests/CreateDirectory001.hs
+++ b/tests/CreateDirectory001.hs
@@ -1,9 +1,13 @@
-{-# LANGUAGE CPP #-}
 module CreateDirectory001 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
   createDirectory testdir
-  T(expectIOErrorType) () isAlreadyExistsError (createDirectory testdir)
+  T.expectIOErrorType _t () isAlreadyExistsError (createDirectory testdir)
   where testdir = "dir"
diff --git a/tests/CreateDirectoryIfMissing001.hs b/tests/CreateDirectoryIfMissing001.hs
--- a/tests/CreateDirectoryIfMissing001.hs
+++ b/tests/CreateDirectoryIfMissing001.hs
@@ -1,7 +1,14 @@
 {-# LANGUAGE CPP #-}
 module CreateDirectoryIfMissing001 where
-#include "util.inl"
-import System.FilePath ((</>), addTrailingPathSeparator)
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import Data.Either (lefts)
+import System.OsPath ((</>), addTrailingPathSeparator)
 
 main :: TestEnv -> IO ()
 main _t = do
@@ -9,7 +16,7 @@
   createDirectoryIfMissing False testdir
   cleanup
 
-  T(expectIOErrorType) () isDoesNotExistError $
+  T.expectIOErrorType _t () isDoesNotExistError $
     createDirectoryIfMissing False testdir_a
 
   createDirectoryIfMissing True  testdir_a
@@ -19,21 +26,21 @@
 
   createDirectoryIfMissing True  (addTrailingPathSeparator testdir_a)
 
-  T(inform) "testing for race conditions ..."
+  T.inform _t "testing for race conditions ..."
   raceCheck1
-  T(inform) "testing for race conditions ..."
+  T.inform _t "testing for race conditions ..."
   raceCheck2
-  T(inform) "done."
+  T.inform _t "done."
   cleanup
 
-  writeFile testdir testdir
-  T(expectIOErrorType) () isAlreadyExistsError $
+  writeFile (so testdir) (so testdir)
+  T.expectIOErrorType _t () isAlreadyExistsError $
     createDirectoryIfMissing False testdir
   removeFile testdir
   cleanup
 
-  writeFile testdir testdir
-  T(expectIOErrorType) () isNotADirectoryError $
+  writeFile (so testdir) (so testdir)
+  T.expectIOErrorType _t () isNotADirectoryError $
     createDirectoryIfMissing True testdir_a
   removeFile testdir
   cleanup
@@ -42,34 +49,35 @@
 
     testname = "CreateDirectoryIfMissing001"
 
-    testdir = testname <> ".d"
+    testdir = os (testname <> ".d")
     testdir_a = testdir </> "a"
 
-    numRepeats = T.readArg _t testname "num-repeats" 10000
+    numRepeats = T.readArg _t testname "num-repeats" 10
     numThreads = T.readArg _t testname "num-threads" 4
 
+    forkPut mvar action = () <$ forkFinally action (putMVar mvar)
+
     -- Look for race conditions (bug #2808 on GHC Trac).  This fails with
     -- +RTS -N2 and directory 1.0.0.2.
     raceCheck1 = do
       m <- newEmptyMVar
-      _ <- forkIO $ do
+      forkPut m $ do
         replicateM_ numRepeats create
-        putMVar m ()
-      _ <- forkIO $ do
+      forkPut m $ do
         replicateM_ numRepeats cleanup
-        putMVar m ()
-      replicateM_ 2 (takeMVar m)
+      results <- replicateM 2 (takeMVar m)
+      T.expectEq _t () [] (show <$> lefts results)
 
     -- This test fails on Windows (see bug #2924 on GHC Trac):
     raceCheck2 = do
       m <- newEmptyMVar
-      replicateM_ numThreads $
-        forkIO $ do
+      replicateM_ numThreads $ do
+        forkPut m $ do
           replicateM_ numRepeats $ do
             create
             cleanup
-          putMVar m ()
-      replicateM_ numThreads (takeMVar m)
+      results <- replicateM numThreads (takeMVar m)
+      T.expectEq _t () [] (show <$> lefts results)
 
     -- createDirectoryIfMissing is allowed to fail with isDoesNotExistError if
     -- another process/thread removes one of the directories during the process
@@ -79,16 +87,19 @@
     -- (see bug #2924 on GHC Trac)
     create =
       createDirectoryIfMissing True testdir_a `catch` \ e ->
-      if isDoesNotExistError e || isPermissionError e || isInappropriateTypeError e
-      then return ()
+      if isDoesNotExistError e
+         || isPermissionError e
+         || isInappropriateTypeError e
+         || ioeGetErrorType e == InvalidArgument
+      then pure ()
       else ioError e
 
-    cleanup = removeDirectoryRecursive testdir `catchAny` \ _ -> return ()
+    cleanup = removeDirectoryRecursive testdir `catchAny` \ _ -> pure ()
 
     catchAny :: IO a -> (SomeException -> IO a) -> IO a
     catchAny = catch
 
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS)
     isNotADirectoryError = isAlreadyExistsError
 #else
     isNotADirectoryError = isInappropriateTypeError
diff --git a/tests/CurrentDirectory001.hs b/tests/CurrentDirectory001.hs
--- a/tests/CurrentDirectory001.hs
+++ b/tests/CurrentDirectory001.hs
@@ -1,6 +1,10 @@
-{-# LANGUAGE CPP #-}
 module CurrentDirectory001 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 import qualified Data.List as List
 
 main :: TestEnv -> IO ()
@@ -8,6 +12,6 @@
   prevDir <- getCurrentDirectory
   createDirectory "dir"
   setCurrentDirectory "dir"
-  T(expectEq) () [".", ".."] . List.sort =<< getDirectoryContents "."
+  T.expectEq _t () [".", ".."] . List.sort =<< getDirectoryContents "."
   setCurrentDirectory prevDir
   removeDirectory "dir"
diff --git a/tests/Directory001.hs b/tests/Directory001.hs
--- a/tests/Directory001.hs
+++ b/tests/Directory001.hs
@@ -1,6 +1,10 @@
-{-# LANGUAGE CPP #-}
 module Directory001 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
@@ -10,7 +14,7 @@
   renameFile "foo/bar" "foo/baz"
   renameDirectory "foo" "bar"
   str' <- readFile "bar/baz"
-  T(expectEq) () str' str
+  T.expectEq _t () str' str
   removeFile "bar/baz"
   removeDirectory "bar"
 
diff --git a/tests/DoesDirectoryExist001.hs b/tests/DoesDirectoryExist001.hs
--- a/tests/DoesDirectoryExist001.hs
+++ b/tests/DoesDirectoryExist001.hs
@@ -1,23 +1,30 @@
 {-# LANGUAGE CPP #-}
 module DoesDirectoryExist001 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
 
   -- [regression test] "/" was not recognised as a directory prior to GHC 6.1
-  T(expect) () =<< doesDirectoryExist rootDir
+  T.expect _t () =<< doesDirectoryExist rootDir
 
   createDirectory "somedir"
 
-  T(expect) () . not =<< doesDirectoryExist "nonexistent"
-  T(expect) () =<< doesDirectoryExist "somedir"
-#ifdef mingw32_HOST_OS
-  T(expect) () =<< doesDirectoryExist "SoMeDiR"
+  T.expect _t () . not =<< doesDirectoryExist ""
+  T.expect _t () . not =<< doesDirectoryExist "nonexistent"
+  T.expect _t () =<< doesDirectoryExist "."
+  T.expect _t () =<< doesDirectoryExist "somedir"
+#if defined(mingw32_HOST_OS)
+  T.expect _t () =<< doesDirectoryExist "SoMeDiR"
 #endif
 
   where
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS)
     rootDir = "C:\\"
 #else
     rootDir = "/"
diff --git a/tests/DoesPathExist.hs b/tests/DoesPathExist.hs
--- a/tests/DoesPathExist.hs
+++ b/tests/DoesPathExist.hs
@@ -1,28 +1,49 @@
 {-# LANGUAGE CPP #-}
 module DoesPathExist where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils (supportsSymlinks)
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
 
-  T(expect) () =<< doesPathExist rootDir
+  T.expect _t () =<< doesPathExist rootDir
 
   createDirectory "somedir"
   writeFile "somefile" "somedata"
   writeFile "\x3c0\x42f\x97f3\xe6\x221e" "somedata"
 
-  T(expect) () . not =<< doesPathExist "nonexistent"
-  T(expect) () =<< doesPathExist "somedir"
-  T(expect) () =<< doesPathExist "somefile"
-  T(expect) () =<< doesPathExist "./somefile"
-#ifdef mingw32_HOST_OS
-  T(expect) () =<< doesPathExist "SoMeDiR"
-  T(expect) () =<< doesPathExist "sOmEfIlE"
+  T.expect _t () . not =<< doesPathExist ""
+  T.expect _t () . not =<< doesPathExist "nonexistent"
+  T.expect _t () =<< doesPathExist "."
+  T.expect _t () =<< doesPathExist "somedir"
+  T.expect _t () =<< doesPathExist "somefile"
+  T.expect _t () =<< doesPathExist "./somefile"
+#if defined(mingw32_HOST_OS)
+  T.expect _t () =<< doesPathExist "SoMeDiR"
+  T.expect _t () =<< doesPathExist "sOmEfIlE"
 #endif
-  T(expect) () =<< doesPathExist "\x3c0\x42f\x97f3\xe6\x221e"
+  T.expect _t () =<< doesPathExist "\x3c0\x42f\x97f3\xe6\x221e"
 
+  supportsSymbolicLinks <- supportsSymlinks
+  when supportsSymbolicLinks $ do
+
+    createDirectoryLink "somedir" "somedirlink"
+    createFileLink "somefile" "somefilelink"
+    createFileLink "nonexistent" "nonexistentlink"
+
+    T.expect _t () =<< doesFileExist "somefilelink"
+    T.expect _t () . not =<< doesDirectoryExist "somefilelink"
+    T.expect _t () =<< doesDirectoryExist "somedirlink"
+    T.expect _t () . not =<< doesFileExist "somedirlink"
+    T.expect _t () . not =<< doesDirectoryExist "nonexistentlink"
+    T.expect _t () . not =<< doesFileExist "nonexistentlink"
+
   where
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS)
     rootDir = "C:\\"
 #else
     rootDir = "/"
diff --git a/tests/FileTime.hs b/tests/FileTime.hs
--- a/tests/FileTime.hs
+++ b/tests/FileTime.hs
@@ -1,6 +1,10 @@
-{-# LANGUAGE CPP #-}
 module FileTime where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 import Data.Time.Clock (addUTCTime, getCurrentTime)
 
 main :: TestEnv -> IO ()
@@ -9,13 +13,13 @@
   let someTimeAgo  = addUTCTime (-3600) now
       someTimeAgo' = addUTCTime (-7200) now
 
-  T(expectIOErrorType) () isDoesNotExistError $
+  T.expectIOErrorType _t () isDoesNotExistError $
     getAccessTime "nonexistent-file"
-  T(expectIOErrorType) () isDoesNotExistError $
+  T.expectIOErrorType _t () isDoesNotExistError $
     setAccessTime "nonexistent-file" someTimeAgo
-  T(expectIOErrorType) () isDoesNotExistError $
+  T.expectIOErrorType _t () isDoesNotExistError $
     getModificationTime "nonexistent-file"
-  T(expectIOErrorType) () isDoesNotExistError $
+  T.expectIOErrorType _t () isDoesNotExistError $
     setModificationTime "nonexistent-file" someTimeAgo
 
   writeFile  "foo" ""
@@ -31,20 +35,27 @@
     mtime2 <- getModificationTime file
 
     -- modification time should be set with at worst 1 sec resolution
-    T(expectNearTime) file mtime  mtime2 1
+    T.expectNearTime _t file mtime  mtime2 1
 
     -- access time should not change, although it may lose some precision
     -- on POSIX systems without 'utimensat'
-    T(expectNearTime) file atime1 atime2 1
+    T.expectNearTime _t file atime1 atime2 1
 
     setAccessTime file atime
 
     atime3 <- getAccessTime file
     mtime3 <- getModificationTime file
 
-    -- access time should be set with at worst 1 sec resolution
-    T(expectNearTime) file atime  atime3 1
+    when setAtime $ do
+      -- access time should be set with at worst 1 sec resolution
+      T.expectNearTime _t file atime atime3 1
 
     -- modification time should not change, although it may lose some precision
     -- on POSIX systems without 'utimensat'
-    T(expectNearTime) file mtime2 mtime3 1
+    T.expectNearTime _t file mtime2 mtime3 1
+
+  where
+
+    testname = "FileTime"
+
+    setAtime = T.readArg _t testname "set-atime" True
diff --git a/tests/FindExecutable.hs b/tests/FindExecutable.hs
new file mode 100644
--- /dev/null
+++ b/tests/FindExecutable.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE CPP #-}
+module FindExecutable where
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+
+main :: TestEnv -> IO ()
+main _t = do
+
+  -- 'find' expected to exist on both Windows and POSIX,
+  -- though we have no idea if it's writable
+  Just _ <- findExecutable "find"
+
+  T.expectEq _t () Nothing =<<
+    findExecutable "__nonexistent_binary_gbowyxcejjawf7r6__"
+
+  -- https://github.com/haskell/directory/issues/187
+  T.expectEq _t () Nothing =<< findExecutable "/"
+  T.expectEq _t () Nothing =<< findExecutable "//"
+#if !defined(mingw32_HOST_OS)
+  T.expectEq _t () Nothing =<< findExecutable "\\"
+  T.expectEq _t () Nothing =<< findExecutable "\\\\"
+  T.expectEq _t () Nothing =<< findExecutable "\\\\localhost\\c$"
+#endif
diff --git a/tests/FindFile001.hs b/tests/FindFile001.hs
--- a/tests/FindFile001.hs
+++ b/tests/FindFile001.hs
@@ -1,10 +1,58 @@
-{-# LANGUAGE CPP #-}
 module FindFile001 where
-#include "util.inl"
-import System.FilePath ((</>))
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import qualified Data.List as List
+import System.OsPath ((</>))
 
 main :: TestEnv -> IO ()
 main _t = do
+
+  createDirectory "bar"
+  createDirectory "qux"
   writeFile "foo" ""
-  found <- findFile ("." : undefined) "foo"
-  T(expectEq) () found (Just ("." </> "foo"))
+  writeFile (so ("bar" </> "foo")) ""
+  writeFile (so ("qux" </> "foo")) ":3"
+
+  -- make sure findFile is lazy enough
+  T.expectEq _t () (Just ("." </> "foo")) =<< findFile ("." : undefined) "foo"
+
+  -- make sure relative paths work
+  T.expectEq _t () (Just ("." </> "bar" </> "foo")) =<<
+    findFile ["."] ("bar" </> "foo")
+
+  T.expectEq _t () (Just ("." </> "foo")) =<< findFile [".", "bar"] "foo"
+  T.expectEq _t () (Just ("bar" </> "foo")) =<< findFile ["bar", "."] "foo"
+
+  let f fn = (== ":3") <$> readFile (so fn)
+  for_ (List.permutations ["qux", "bar", "."]) $ \ ds -> do
+
+    let (match, noMatch) = List.partition (== "qux") ds
+    match0 : _ <- pure match
+    noMatch0 : _ <- pure noMatch
+
+    T.expectEq _t ds (Just (match0 </> "foo")) =<<
+      findFileWith f ds "foo"
+
+    T.expectEq _t ds ((</> "foo") <$> match) =<< findFilesWith f ds "foo"
+
+    T.expectEq _t ds (Just (noMatch0 </> "foo")) =<<
+      findFileWith ((not <$>) . f) ds "foo"
+
+    T.expectEq _t ds ((</> "foo") <$> noMatch) =<<
+      findFilesWith ((not <$>) . f) ds "foo"
+
+    T.expectEq _t ds Nothing =<< findFileWith (\ _ -> pure False) ds "foo"
+
+    T.expectEq _t ds [] =<< findFilesWith (\ _ -> pure False) ds "foo"
+
+  -- make sure absolute paths are handled properly irrespective of 'dirs'
+  -- https://github.com/haskell/directory/issues/72
+  absPath <- makeAbsolute ("bar" </> "foo")
+  absPath2 <- makeAbsolute ("bar" </> "nonexistent")
+  T.expectEq _t () (Just absPath) =<< findFile [] absPath
+  T.expectEq _t () Nothing =<< findFile [] absPath2
diff --git a/tests/GetDirContents001.hs b/tests/GetDirContents001.hs
--- a/tests/GetDirContents001.hs
+++ b/tests/GetDirContents001.hs
@@ -1,23 +1,28 @@
-{-# LANGUAGE CPP #-}
 module GetDirContents001 where
-#include "util.inl"
-import System.FilePath ((</>))
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath ((</>))
 import qualified Data.List as List
 
 main :: TestEnv -> IO ()
 main _t = do
   createDirectory dir
-  T(expectEq) () specials . List.sort =<<
+  T.expectEq _t () specials . List.sort =<<
     getDirectoryContents dir
-  T(expectEq) () [] . List.sort =<<
+  T.expectEq _t () [] . List.sort =<<
     listDirectory dir
   names <- for [1 .. 100 :: Int] $ \ i -> do
-    let name = 'f' : show i
-    writeFile (dir </> name) ""
-    return name
-  T(expectEq) () (List.sort (specials <> names)) . List.sort =<<
+    let name = "f" <> os (show i)
+    writeFile (so (dir </> name)) ""
+    pure name
+  T.expectEq _t () (List.sort (specials <> names)) . List.sort =<<
     getDirectoryContents dir
-  T(expectEq) () (List.sort names) . List.sort =<<
+  T.expectEq _t () (List.sort names) . List.sort =<<
     listDirectory dir
   where dir      = "dir"
         specials = [".", ".."]
diff --git a/tests/GetDirContents002.hs b/tests/GetDirContents002.hs
--- a/tests/GetDirContents002.hs
+++ b/tests/GetDirContents002.hs
@@ -1,8 +1,12 @@
-{-# LANGUAGE CPP #-}
 module GetDirContents002 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
-  T(expectIOErrorType) () isDoesNotExistError $
+  T.expectIOErrorType _t () isDoesNotExistError $
     getDirectoryContents "nonexistent"
diff --git a/tests/GetFileSize.hs b/tests/GetFileSize.hs
--- a/tests/GetFileSize.hs
+++ b/tests/GetFileSize.hs
@@ -1,17 +1,19 @@
-{-# LANGUAGE CPP #-}
 module GetFileSize where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
 
-  withBinaryFile "emptyfile" WriteMode $ \ _ -> do
-    return ()
-  withBinaryFile "testfile" WriteMode $ \ h -> do
-    hPutStr h string
+  writeFile "emptyfile" ""
+  writeFile "testfile" string
 
-  T(expectEq) () 0 =<< getFileSize "emptyfile"
-  T(expectEq) () (fromIntegral (length string)) =<< getFileSize "testfile"
+  T.expectEq _t () 0 =<< getFileSize "emptyfile"
+  T.expectEq _t () (fromIntegral (length string)) =<< getFileSize "testfile"
 
   where
     string = "The quick brown fox jumps over the lazy dog."
diff --git a/tests/GetHomeDirectory001.hs b/tests/GetHomeDirectory001.hs
--- a/tests/GetHomeDirectory001.hs
+++ b/tests/GetHomeDirectory001.hs
@@ -1,15 +1,20 @@
-{-# LANGUAGE CPP #-}
 module GetHomeDirectory001 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
   homeDir <- getHomeDirectory
-  T(expect) () (homeDir /= "") -- sanity check
+  T.expect _t () (homeDir /= mempty) -- sanity check
   _ <- getAppUserDataDirectory   "test"
   _ <- getXdgDirectory XdgCache  "test"
   _ <- getXdgDirectory XdgConfig "test"
   _ <- getXdgDirectory XdgData   "test"
+  _ <- getXdgDirectory XdgState  "test"
   _ <- getUserDocumentsDirectory
   _ <- getTemporaryDirectory
-  return ()
+  pure ()
diff --git a/tests/GetHomeDirectory002.hs b/tests/GetHomeDirectory002.hs
new file mode 100644
--- /dev/null
+++ b/tests/GetHomeDirectory002.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE CPP #-}
+module GetHomeDirectory002 where
+
+#if !defined(mingw32_HOST_OS)
+import System.Posix.Env
+#endif
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+
+-- Test that the getpwuid_r fallback works.
+-- This is only relevant on unix.
+main :: TestEnv -> IO ()
+main _t = do
+#if !defined(mingw32_HOST_OS)
+  unsetEnv "HOME"
+#endif
+  _ <- getHomeDirectory
+  T.expect _t () True -- avoid warnings about redundant imports
diff --git a/tests/GetPermissions001.hs b/tests/GetPermissions001.hs
--- a/tests/GetPermissions001.hs
+++ b/tests/GetPermissions001.hs
@@ -1,6 +1,10 @@
-{-# LANGUAGE CPP #-}
 module GetPermissions001 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
@@ -10,37 +14,54 @@
   checkOrdinary
   checkTrailingSlash
 
+  -- 'writable' is the only permission that can be changed on Windows
+  writeFile "foo.txt" ""
+  foo <- makeAbsolute "foo.txt"
+  modifyPermissions "foo.txt" (\ p -> p { writable = False })
+  T.expect _t () =<< not . writable <$> getPermissions "foo.txt"
+  modifyPermissions "foo.txt" (\ p -> p { writable = True })
+  T.expect _t () =<< writable <$> getPermissions "foo.txt"
+  modifyPermissions "foo.txt" (\ p -> p { writable = False })
+  T.expect _t () =<< not . writable <$> getPermissions "foo.txt"
+  modifyPermissions foo (\ p -> p { writable = True })
+  T.expect _t () =<< writable <$> getPermissions foo
+  modifyPermissions foo (\ p -> p { writable = False })
+  T.expect _t () =<< not . writable <$> getPermissions foo
+
+  -- test empty path
+  modifyPermissions "" id
+
   where
 
     checkCurrentDir = do
       -- since the current directory is created by the test runner,
       -- it should be readable, writable, and searchable
       p <- getPermissions "."
-      T(expect) () (readable p)
-      T(expect) () (writable p)
-      T(expect) () (not (executable p))
-      T(expect) () (searchable p)
+      T.expect _t () (readable p)
+      T.expect _t () (writable p)
+      T.expect _t () (not (executable p))
+      T.expect _t () (searchable p)
 
     checkExecutable = do
       -- 'find' expected to exist on both Windows and POSIX,
       -- though we have no idea if it's writable
       Just f <- findExecutable "find"
       p <- getPermissions f
-      T(expect) () (readable p)
-      T(expect) () (executable p)
-      T(expect) () (not (searchable p))
+      T.expect _t () (readable p)
+      T.expect _t () (executable p)
+      T.expect _t () (not (searchable p))
 
     checkOrdinary = do
       writeFile "foo" ""
       p <- getPermissions "foo"
-      T(expect) () (readable p)
-      T(expect) () (writable p)
-      T(expect) () (not (executable p))
-      T(expect) () (not (searchable p))
+      T.expect _t () (readable p)
+      T.expect _t () (writable p)
+      T.expect _t () (not (executable p))
+      T.expect _t () (not (searchable p))
 
     -- [regression test] (issue #9)
     -- Windows doesn't like trailing path separators
     checkTrailingSlash = do
       createDirectory "bar"
       _ <- getPermissions "bar/"
-      return ()
+      pure ()
diff --git a/tests/LongPaths.hs b/tests/LongPaths.hs
new file mode 100644
--- /dev/null
+++ b/tests/LongPaths.hs
@@ -0,0 +1,65 @@
+module LongPaths where
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath ((</>))
+
+main :: TestEnv -> IO ()
+main _t = do
+  let longName = mconcat (replicate 10 "its_very_long")
+  longDir <- makeAbsolute (longName </> longName)
+
+  supportsLongPaths <- do
+      -- create 2 dirs because 1 path segment by itself can't exceed MAX_PATH
+      -- tests: [createDirectory]
+      createDirectory =<< makeAbsolute longName
+      createDirectory longDir
+      pure True
+    `catchIOError` \ _ ->
+      pure False
+
+  -- skip tests on file systems that do not support long paths
+  when supportsLongPaths $ do
+
+    -- test relative paths
+    let relDir = longName </> mconcat (replicate 8 "yeah_its_long")
+    createDirectory relDir
+    T.expect _t () =<< doesDirectoryExist relDir
+    T.expectEq _t () [] =<< listDirectory relDir
+    setPermissions relDir emptyPermissions
+    T.expectEq _t () False =<< writable <$> getPermissions relDir
+
+    writeFile "foobar.txt" "^.^" -- writeFile does not support long paths yet
+
+    -- tests: [renamePath], [copyFileWithMetadata]
+    renamePath "foobar.txt" (longDir </> "foobar_tmp.txt")
+    renamePath (longDir </> "foobar_tmp.txt") (longDir </> "foobar.txt")
+    copyFileWithMetadata (longDir </> "foobar.txt")
+                         (longDir </> "foobar_copy.txt")
+
+    -- tests: [doesDirectoryExist], [doesFileExist], [doesPathExist]
+    T.expect _t () =<< doesDirectoryExist longDir
+    T.expect _t () =<< doesFileExist (longDir </> "foobar.txt")
+    T.expect _t () =<< doesPathExist longDir
+    T.expect _t () =<< doesPathExist (longDir </> "foobar.txt")
+
+    -- tests: [getFileSize], [getModificationTime]
+    T.expectEq _t () 3 =<< getFileSize (longDir </> "foobar.txt")
+    _ <- getModificationTime (longDir </> "foobar.txt")
+
+    supportsSymbolicLinks <- supportsSymlinks
+    when supportsSymbolicLinks $ do
+
+      -- tests: [createDirectoryLink], [getSymbolicLinkTarget], [listDirectory]
+      -- also tests expansion of "." and ".."
+      createDirectoryLink "." (longDir </> "link")
+      _ <- listDirectory (longDir </> ".." </> longName </> "link")
+      T.expectEq _t () "." =<<
+        getSymbolicLinkTarget (longDir </> "." </> "link")
+
+      pure ()
+
+  -- [removeFile], [removeDirectory] are automatically tested by the cleanup
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -11,22 +11,27 @@
 import qualified DoesDirectoryExist001
 import qualified DoesPathExist
 import qualified FileTime
+import qualified FindExecutable
 import qualified FindFile001
 import qualified GetDirContents001
 import qualified GetDirContents002
 import qualified GetFileSize
 import qualified GetHomeDirectory001
+import qualified GetHomeDirectory002
 import qualified GetPermissions001
+import qualified LongPaths
 import qualified MakeAbsolute
+import qualified MinimizeNameConflicts
 import qualified PathIsSymbolicLink
 import qualified RemoveDirectoryRecursive001
 import qualified RemovePathForcibly
 import qualified RenameDirectory
 import qualified RenameFile001
 import qualified RenamePath
-import qualified Safe
+import qualified Simplify
 import qualified T8482
 import qualified WithCurrentDirectory
+import qualified Xdg
 
 main :: IO ()
 main = T.testMain $ \ _t -> do
@@ -41,19 +46,24 @@
   T.isolatedRun _t "DoesDirectoryExist001" DoesDirectoryExist001.main
   T.isolatedRun _t "DoesPathExist" DoesPathExist.main
   T.isolatedRun _t "FileTime" FileTime.main
+  T.isolatedRun _t "FindExecutable" FindExecutable.main
   T.isolatedRun _t "FindFile001" FindFile001.main
   T.isolatedRun _t "GetDirContents001" GetDirContents001.main
   T.isolatedRun _t "GetDirContents002" GetDirContents002.main
   T.isolatedRun _t "GetFileSize" GetFileSize.main
   T.isolatedRun _t "GetHomeDirectory001" GetHomeDirectory001.main
+  T.isolatedRun _t "GetHomeDirectory002" GetHomeDirectory002.main
   T.isolatedRun _t "GetPermissions001" GetPermissions001.main
+  T.isolatedRun _t "LongPaths" LongPaths.main
   T.isolatedRun _t "MakeAbsolute" MakeAbsolute.main
+  T.isolatedRun _t "MinimizeNameConflicts" MinimizeNameConflicts.main
   T.isolatedRun _t "PathIsSymbolicLink" PathIsSymbolicLink.main
   T.isolatedRun _t "RemoveDirectoryRecursive001" RemoveDirectoryRecursive001.main
   T.isolatedRun _t "RemovePathForcibly" RemovePathForcibly.main
   T.isolatedRun _t "RenameDirectory" RenameDirectory.main
   T.isolatedRun _t "RenameFile001" RenameFile001.main
   T.isolatedRun _t "RenamePath" RenamePath.main
-  T.isolatedRun _t "Safe" Safe.main
+  T.isolatedRun _t "Simplify" Simplify.main
   T.isolatedRun _t "T8482" T8482.main
   T.isolatedRun _t "WithCurrentDirectory" WithCurrentDirectory.main
+  T.isolatedRun _t "Xdg" Xdg.main
diff --git a/tests/MakeAbsolute.hs b/tests/MakeAbsolute.hs
--- a/tests/MakeAbsolute.hs
+++ b/tests/MakeAbsolute.hs
@@ -1,33 +1,53 @@
 {-# LANGUAGE CPP #-}
 module MakeAbsolute where
-#include "util.inl"
-import System.FilePath ((</>), addTrailingPathSeparator,
-                        dropTrailingPathSeparator, normalise)
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath ((</>), addTrailingPathSeparator,
+                      dropTrailingPathSeparator, normalise)
+#if defined(mingw32_HOST_OS)
+import System.Directory.Internal
+import System.OsPath (takeDrive, toChar, unpack)
+#endif
 
 main :: TestEnv -> IO ()
 main _t = do
   dot <- makeAbsolute ""
   dot2 <- makeAbsolute "."
   dot3 <- makeAbsolute "./."
-  T(expectEq) () dot (dropTrailingPathSeparator dot)
-  T(expectEq) () dot dot2
-  T(expectEq) () dot dot3
+  T.expectEq _t () dot (dropTrailingPathSeparator dot)
+  T.expectEq _t () dot dot2
+  T.expectEq _t () dot dot3
 
   sdot <- makeAbsolute "./"
   sdot2 <- makeAbsolute "././"
-  T(expectEq) () sdot (addTrailingPathSeparator sdot)
-  T(expectEq) () sdot sdot2
+  T.expectEq _t () sdot (addTrailingPathSeparator sdot)
+  T.expectEq _t () sdot sdot2
 
   foo <- makeAbsolute "foo"
   foo2 <- makeAbsolute "foo/."
   foo3 <- makeAbsolute "./foo"
-  T(expectEq) () foo (normalise (dot </> "foo"))
-  T(expectEq) () foo foo2
-  T(expectEq) () foo foo3
+  T.expectEq _t () foo (normalise (dot </> "foo"))
+  T.expectEq _t () foo foo2
+  T.expectEq _t () foo foo3
 
   sfoo <- makeAbsolute "foo/"
   sfoo2 <- makeAbsolute "foo/./"
   sfoo3 <- makeAbsolute "./foo/"
-  T(expectEq) () sfoo (normalise (dot </> "foo/"))
-  T(expectEq) () sfoo sfoo2
-  T(expectEq) () sfoo sfoo3
+  T.expectEq _t () sfoo (normalise (dot </> "foo/"))
+  T.expectEq _t () sfoo sfoo2
+  T.expectEq _t () sfoo sfoo3
+
+#if defined(mingw32_HOST_OS)
+  cwd <- getCurrentDirectory
+  cwdDriveLetter : _ <- pure (unpack (takeDrive cwd))
+  let driveLetter = toUpper (toChar cwdDriveLetter)
+  let driveLetter' = if driveLetter == 'Z' then 'A' else succ driveLetter
+  drp1 <- makeAbsolute (os (driveLetter : ":foobar"))
+  drp2 <- makeAbsolute (os (driveLetter' : ":foobar"))
+  T.expectEq _t () drp1 =<< makeAbsolute "foobar"
+  T.expectEq _t () drp2 (os (driveLetter' : ":\\foobar"))
+#endif
diff --git a/tests/MinimizeNameConflicts.hs b/tests/MinimizeNameConflicts.hs
new file mode 100644
--- /dev/null
+++ b/tests/MinimizeNameConflicts.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE CPP #-}
+module MinimizeNameConflicts
+  ( main
+  , module System.Directory.OsPath
+#if defined(mingw32_HOST_OS)
+  , module System.Win32
+#else
+  , module System.Posix
+#endif
+  ) where
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+#if defined(mingw32_HOST_OS)
+import System.Win32 hiding
+  ( copyFile
+  , createDirectory
+  , getCurrentDirectory
+  , getTemporaryDirectory
+  , removeDirectory
+  , setCurrentDirectory
+  )
+#else
+import System.Posix hiding
+  ( createDirectory
+  , isSymbolicLink
+  , removeDirectory
+  )
+#endif
+
+-- This is just a compile-test to check for name conflicts between directory
+-- and other boot libraries. See for example:
+-- https://github.com/haskell/directory/issues/52
+main :: TestEnv -> IO ()
+main _t = do
+  T.expect _t ("no-op" :: String) True
diff --git a/tests/PathIsSymbolicLink.hs b/tests/PathIsSymbolicLink.hs
--- a/tests/PathIsSymbolicLink.hs
+++ b/tests/PathIsSymbolicLink.hs
@@ -1,18 +1,36 @@
-{-# LANGUAGE CPP #-}
 module PathIsSymbolicLink where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
 import TestUtils
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
-  success <- (createSymbolicLink "x" "y" >> return True)
-#ifdef mingw32_HOST_OS
-    -- only test if symbolic links can be created
-    -- (usually disabled on Windows by group policy)
-    `catchIOError` \ e ->
-      if isPermissionError e
-      then return False
-      else ioError e
-#endif
-  when success $
-    T(expect) () =<< pathIsSymbolicLink "y"
+  supportsSymbolicLinks <- supportsSymlinks
+  when supportsSymbolicLinks $ do
+
+    createFileLink "x" "y"
+    createDirectoryLink "a" "b"
+
+    T.expect _t () =<< pathIsSymbolicLink "y"
+    T.expect _t () =<< pathIsSymbolicLink "b"
+    T.expectEq _t () "x" =<< getSymbolicLinkTarget "y"
+    T.expectEq _t () "a" =<< getSymbolicLinkTarget "b"
+    T.expectEq _t () False =<< doesFileExist "y"
+    T.expectEq _t () False =<< doesDirectoryExist "b"
+
+    writeFile "x" ""
+    createDirectory "a"
+
+    T.expect _t () =<< doesFileExist "y"
+    T.expect _t () =<< doesDirectoryExist "b"
+
+    removeFile "y"
+    removeDirectoryLink "b"
+
+    T.expectIOErrorType _t () isDoesNotExistError (pathIsSymbolicLink "y")
+    T.expectIOErrorType _t () isDoesNotExistError (pathIsSymbolicLink "b")
+    T.expectEq _t () False =<< doesFileExist "y"
+    T.expectEq _t () False =<< doesDirectoryExist "b"
diff --git a/tests/RemoveDirectoryRecursive001.hs b/tests/RemoveDirectoryRecursive001.hs
--- a/tests/RemoveDirectoryRecursive001.hs
+++ b/tests/RemoveDirectoryRecursive001.hs
@@ -1,9 +1,14 @@
 {-# LANGUAGE CPP #-}
 module RemoveDirectoryRecursive001 where
-#include "util.inl"
-import System.FilePath ((</>), normalise)
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils (modifyPermissions, symlinkOrCopy)
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath ((</>), normalise)
 import qualified Data.List as List
-import TestUtils
 
 main :: TestEnv -> IO ()
 main _t = do
@@ -12,9 +17,9 @@
   -- clean up junk from previous invocations
 
   modifyPermissions (tmp "c") (\ p -> p { writable = True })
-    `catchIOError` \ _ -> return ()
+    `catchIOError` \ _ -> pure ()
   removeDirectoryRecursive tmpD
-    `catchIOError` \ _ -> return ()
+    `catchIOError` \ _ -> pure ()
 
   ------------------------------------------------------------
   -- set up
@@ -24,40 +29,40 @@
   createDirectoryIfMissing True (tmp "a/z")
   createDirectoryIfMissing True (tmp "b")
   createDirectoryIfMissing True (tmp "c")
-  writeFile (tmp "a/x/w/u") "foo"
-  writeFile (tmp "a/t")     "bar"
-  tryCreateSymbolicLink (normalise "../a") (tmp "b/g")
-  tryCreateSymbolicLink (normalise "../b") (tmp "c/h")
-  tryCreateSymbolicLink (normalise "a")    (tmp "d")
+  writeFile (so (tmp "a/x/w/u")) "foo"
+  writeFile (so (tmp "a/t"))     "bar"
+  symlinkOrCopy (normalise "../a") (tmp "b/g")
+  symlinkOrCopy (normalise "../b") (tmp "c/h")
+  symlinkOrCopy (normalise "a")    (tmp "d")
   modifyPermissions (tmp "c") (\ p -> p { writable = False })
 
   ------------------------------------------------------------
   -- tests
 
-  T(expectEq) () [".", "..", "a", "b", "c", "d"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a", "b", "c", "d"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "a")
-  T(expectEq) () [".", "..", "g"] . List.sort =<<
+  T.expectEq _t () [".", "..", "g"] . List.sort =<<
     getDirectoryContents (tmp "b")
-  T(expectEq) () [".", "..", "h"] . List.sort =<<
+  T.expectEq _t () [".", "..", "h"] . List.sort =<<
     getDirectoryContents (tmp "c")
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "d")
 
   removeDirectoryRecursive (tmp "d")
     `catchIOError` \ _ -> removeFile      (tmp "d")
-#ifdef mingw32_HOST_OS
+#if defined(mingw32_HOST_OS)
     `catchIOError` \ _ -> removeDirectory (tmp "d")
 #endif
 
-  T(expectEq) () [".", "..", "a", "b", "c"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a", "b", "c"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "a")
-  T(expectEq) () [".", "..", "g"] . List.sort =<<
+  T.expectEq _t () [".", "..", "g"] . List.sort =<<
     getDirectoryContents (tmp "b")
-  T(expectEq) () [".", "..", "h"] . List.sort =<<
+  T.expectEq _t () [".", "..", "h"] . List.sort =<<
     getDirectoryContents (tmp "c")
 
   removeDirectoryRecursive (tmp "c")
@@ -65,25 +70,25 @@
       modifyPermissions (tmp "c") (\ p -> p { writable = True })
       removeDirectoryRecursive (tmp "c")
 
-  T(expectEq) () [".", "..", "a", "b"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a", "b"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
    getDirectoryContents (tmp "a")
-  T(expectEq) () [".", "..", "g"] . List.sort =<<
+  T.expectEq _t () [".", "..", "g"] . List.sort =<<
     getDirectoryContents (tmp "b")
 
   removeDirectoryRecursive (tmp "b")
 
-  T(expectEq) () [".", "..", "a"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "a")
 
   removeDirectoryRecursive (tmp "a")
 
-  T(expectEq) () [".", ".."] . List.sort =<<
+  T.expectEq _t () [".", ".."] . List.sort =<<
     getDirectoryContents  tmpD
 
   where testName = "removeDirectoryRecursive001"
-        tmpD  = testName ++ ".tmp"
+        tmpD  = testName <> ".tmp"
         tmp s = tmpD </> normalise s
diff --git a/tests/RemovePathForcibly.hs b/tests/RemovePathForcibly.hs
--- a/tests/RemovePathForcibly.hs
+++ b/tests/RemovePathForcibly.hs
@@ -1,9 +1,13 @@
-{-# LANGUAGE CPP #-}
 module RemovePathForcibly where
-#include "util.inl"
-import System.FilePath ((</>), normalise)
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils (hardLinkOrCopy, modifyPermissions, symlinkOrCopy)
+import Util (TestEnv)
+import qualified Util as T
+import System.Directory.Internal
+import System.OsPath ((</>), normalise)
 import qualified Data.List as List
-import TestUtils
 
 main :: TestEnv -> IO ()
 main _t = do
@@ -12,9 +16,9 @@
   -- clean up junk from previous invocations
 
   modifyPermissions (tmp "c") (\ p -> p { writable = True })
-    `catchIOError` \ _ -> return ()
+    `catchIOError` \ _ -> pure ()
   removePathForcibly tmpD
-    `catchIOError` \ _ -> return ()
+    `catchIOError` \ _ -> pure ()
 
   ------------------------------------------------------------
   -- set up
@@ -25,12 +29,12 @@
   createDirectoryIfMissing True (tmp "b")
   createDirectoryIfMissing True (tmp "c")
   createDirectoryIfMissing True (tmp "f")
-  writeFile (tmp "a/x/w/u") "foo"
-  writeFile (tmp "a/t")     "bar"
-  writeFile (tmp "f/s")     "qux"
-  tryCreateSymbolicLink (normalise "../a") (tmp "b/g")
-  tryCreateSymbolicLink (normalise "../b") (tmp "c/h")
-  tryCreateSymbolicLink (normalise "a")    (tmp "d")
+  writeFile (so (tmp "a/x/w/u")) "foo"
+  writeFile (so (tmp "a/t"))     "bar"
+  writeFile (so (tmp "f/s"))     "qux"
+  symlinkOrCopy (normalise "../a") (tmp "b/g")
+  symlinkOrCopy (normalise "../b") (tmp "c/h")
+  symlinkOrCopy (normalise "a")    (tmp "d")
   setPermissions (tmp "f/s") emptyPermissions
   setPermissions (tmp "f") emptyPermissions
 
@@ -40,49 +44,59 @@
   removePathForcibly (tmp "f")
   removePathForcibly (tmp "e") -- intentionally non-existent
 
-  T(expectEq) () [".", "..", "a", "b", "c", "d"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a", "b", "c", "d"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "a")
-  T(expectEq) () [".", "..", "g"] . List.sort =<<
+  T.expectEq _t () [".", "..", "g"] . List.sort =<<
     getDirectoryContents (tmp "b")
-  T(expectEq) () [".", "..", "h"] . List.sort =<<
+  T.expectEq _t () [".", "..", "h"] . List.sort =<<
     getDirectoryContents (tmp "c")
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "d")
 
   removePathForcibly (tmp "d")
 
-  T(expectEq) () [".", "..", "a", "b", "c"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a", "b", "c"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "a")
-  T(expectEq) () [".", "..", "g"] . List.sort =<<
+  T.expectEq _t () [".", "..", "g"] . List.sort =<<
     getDirectoryContents (tmp "b")
-  T(expectEq) () [".", "..", "h"] . List.sort =<<
+  T.expectEq _t () [".", "..", "h"] . List.sort =<<
     getDirectoryContents (tmp "c")
 
   removePathForcibly (tmp "c")
 
-  T(expectEq) () [".", "..", "a", "b"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a", "b"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
    getDirectoryContents (tmp "a")
-  T(expectEq) () [".", "..", "g"] . List.sort =<<
+  T.expectEq _t () [".", "..", "g"] . List.sort =<<
     getDirectoryContents (tmp "b")
 
   removePathForcibly (tmp "b")
 
-  T(expectEq) () [".", "..", "a"] . List.sort =<<
+  T.expectEq _t () [".", "..", "a"] . List.sort =<<
     getDirectoryContents  tmpD
-  T(expectEq) () [".", "..", "t", "x", "y", "z"] . List.sort =<<
+  T.expectEq _t () [".", "..", "t", "x", "y", "z"] . List.sort =<<
     getDirectoryContents (tmp "a")
 
   removePathForcibly (tmp "a")
 
-  T(expectEq) () [".", ".."] . List.sort =<<
+  T.expectEq _t () [".", ".."] . List.sort =<<
     getDirectoryContents  tmpD
 
+  ----------------------------------------------------------------------
+  -- regression test for https://github.com/haskell/directory/issues/135
+  
+  writeFile "hl1" "hardlinked"
+  setPermissions "hl1" emptyPermissions
+  origPermissions <- getPermissions "hl1"
+  hardLinkOrCopy "hl1" "hl2"
+  removePathForcibly "hl2"
+  T.expectEq _t () origPermissions =<< getPermissions "hl1"
+
   where testName = "removePathForcibly"
-        tmpD  = testName ++ ".tmp"
+        tmpD  = testName <> ".tmp"
         tmp s = tmpD </> normalise s
diff --git a/tests/RenameDirectory.hs b/tests/RenameDirectory.hs
--- a/tests/RenameDirectory.hs
+++ b/tests/RenameDirectory.hs
@@ -1,10 +1,14 @@
-{-# LANGUAGE CPP #-}
 module RenameDirectory where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
   createDirectory "a"
-  T(expectEq) () ["a"] =<< listDirectory "."
+  T.expectEq _t () ["a"] =<< listDirectory "."
   renameDirectory "a" "b"
-  T(expectEq) () ["b"] =<< listDirectory "."
+  T.expectEq _t () ["b"] =<< listDirectory "."
diff --git a/tests/RenameFile001.hs b/tests/RenameFile001.hs
--- a/tests/RenameFile001.hs
+++ b/tests/RenameFile001.hs
@@ -1,15 +1,20 @@
-{-# LANGUAGE CPP #-}
 module RenameFile001 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
   writeFile tmp1 contents1
-  renameFile tmp1 tmp2
-  T(expectEq) () contents1 =<< readFile tmp2
+  renameFile (os tmp1) (os tmp2)
+  T.expectEq _t () contents1 =<< readFile tmp2
   writeFile tmp1 contents2
-  renameFile tmp2 tmp1
-  T(expectEq) () contents1 =<< readFile tmp1
+  renameFile (os tmp2) (os tmp1)
+  T.expectEq _t () contents1 =<< readFile tmp1
   where
     tmp1 = "tmp1"
     tmp2 = "tmp2"
diff --git a/tests/RenamePath.hs b/tests/RenamePath.hs
--- a/tests/RenamePath.hs
+++ b/tests/RenamePath.hs
@@ -1,21 +1,26 @@
-{-# LANGUAGE CPP #-}
 module RenamePath where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
 main :: TestEnv -> IO ()
 main _t = do
 
   createDirectory "a"
-  T(expectEq) () ["a"] =<< listDirectory "."
+  T.expectEq _t () ["a"] =<< listDirectory "."
   renamePath "a" "b"
-  T(expectEq) () ["b"] =<< listDirectory "."
+  T.expectEq _t () ["b"] =<< listDirectory "."
 
   writeFile tmp1 contents1
-  renamePath tmp1 tmp2
-  T(expectEq) () contents1 =<< readFile tmp2
+  renamePath (os tmp1) (os tmp2)
+  T.expectEq _t () contents1 =<< readFile tmp2
   writeFile tmp1 contents2
-  renamePath tmp2 tmp1
-  T(expectEq) () contents1 =<< readFile tmp1
+  renamePath (os tmp2) (os tmp1)
+  T.expectEq _t () contents1 =<< readFile tmp1
 
   where
     tmp1 = "tmp1"
diff --git a/tests/Safe.hs b/tests/Safe.hs
deleted file mode 100644
--- a/tests/Safe.hs
+++ /dev/null
@@ -1,7 +0,0 @@
--- Verify that System.Directory is indeed Safe (regression test for issue #30)
-{-# LANGUAGE Safe #-}
-module Safe where
-import System.Directory ()
-
-main :: a -> IO ()
-main _ = return ()
diff --git a/tests/Simplify.hs b/tests/Simplify.hs
new file mode 100644
--- /dev/null
+++ b/tests/Simplify.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE CPP #-}
+module Simplify where
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal (simplifyWindows)
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath (normalise)
+
+main :: TestEnv -> IO ()
+main _t = do
+  T.expectIOErrorType _t () (const True) (setCurrentDirectory "")
+  T.expectEq _t () (simplifyWindows "") ""
+  T.expectEq _t () (simplifyWindows ".") "."
+  T.expectEq _t () (simplifyWindows "a///b") (normalise "a/b")
+  T.expectEq _t () (simplifyWindows "./a//b") (normalise "a/b")
+  T.expectEq _t () (simplifyWindows "a/../../../b/.") (normalise "../../b")
+  T.expectEq _t () (simplifyWindows "a/.././b/./") (normalise "b/")
+  T.expectEq _t () (simplifyWindows "C:/a/../b") (normalise "C:/b")
+  T.expectEq _t () (simplifyWindows "\\\\?\\./a\\../b") "\\\\?\\./a\\../b"
+  T.expectEq _t () (simplifyWindows "C:/a") (normalise "C:/a")
+  T.expectEq _t () (simplifyWindows "/a") (normalise "/a")
+#ifdef mingw32_HOST_OS
+  T.expectEq _t () (simplifyWindows "C:") "C:"
+  T.expectEq _t () (simplifyWindows "c:\\\\") "C:\\"
+  T.expectEq _t () (simplifyWindows "C:.") "C:"
+  T.expectEq _t () (simplifyWindows "C:.\\\\") "C:.\\"
+  T.expectEq _t () (simplifyWindows "C:..") "C:.."
+  T.expectEq _t () (simplifyWindows "C:..\\") "C:..\\"
+  T.expectEq _t () (simplifyWindows "C:\\.\\") "C:\\"
+  T.expectEq _t () (simplifyWindows "C:\\a") "C:\\a"
+  T.expectEq _t () (simplifyWindows "C:\\a\\\\b\\") "C:\\a\\b\\"
+  T.expectEq _t () (simplifyWindows "\\\\a\\b") "\\\\a\\b"
+  T.expectEq _t () (simplifyWindows "//a\\b/c/./d") "\\\\a\\b/c/./d"
+  T.expectEq _t () (simplifyWindows "/.") "\\"
+  T.expectEq _t () (simplifyWindows "/./") "\\"
+  T.expectEq _t () (simplifyWindows "/../") "\\"
+  T.expectEq _t () (simplifyWindows "\\a\\.") "\\a"
+  T.expectEq _t () (simplifyWindows "//?") "\\\\?"
+  T.expectEq _t () (simplifyWindows "//?\\") "\\\\?\\"
+  T.expectEq _t () (simplifyWindows "//?/a/b") "\\\\?\\a/b"
+#endif
diff --git a/tests/T8482.hs b/tests/T8482.hs
--- a/tests/T8482.hs
+++ b/tests/T8482.hs
@@ -1,18 +1,23 @@
-{-# LANGUAGE CPP #-}
 module T8482 where
-#include "util.inl"
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
 
-tmp1 :: FilePath
+tmp1 :: OsPath
 tmp1 = "T8482.tmp1"
 
-testdir :: FilePath
+testdir :: OsPath
 testdir = "T8482.dir"
 
 main :: TestEnv -> IO ()
 main _t = do
-  writeFile tmp1 "hello"
+  writeFile (so tmp1) "hello"
   createDirectory testdir
-  T(expectIOErrorType) () (is InappropriateType) (renameFile testdir tmp1)
-  T(expectIOErrorType) () (is InappropriateType) (renameFile tmp1    testdir)
-  T(expectIOErrorType) () (is InappropriateType) (renameFile tmp1    ".")
+  T.expectIOErrorType _t () (is InappropriateType) (renameFile testdir tmp1)
+  T.expectIOErrorType _t () (is InappropriateType) (renameFile tmp1    testdir)
+  T.expectIOErrorType _t () (is InappropriateType) (renameFile tmp1    ".")
   where is t = (== t) . ioeGetErrorType
diff --git a/tests/TestUtils.hs b/tests/TestUtils.hs
--- a/tests/TestUtils.hs
+++ b/tests/TestUtils.hs
@@ -1,38 +1,28 @@
-{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+{-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
+-- | Utility functions specific to 'directory' tests
 module TestUtils
   ( copyPathRecursive
-  , createSymbolicLink
+  , hardLinkOrCopy
   , modifyPermissions
-  , tryCreateSymbolicLink
+  , symlinkOrCopy
+  , supportsSymlinks
   ) where
 import Prelude ()
 import System.Directory.Internal.Prelude
-import System.Directory
-import System.FilePath ((</>))
-#ifdef mingw32_HOST_OS
-import System.FilePath (takeDirectory)
+import System.Directory.Internal
+import System.Directory.OsPath
+import Data.String (IsString(fromString))
+import System.OsPath ((</>), normalise, takeDirectory)
+#if defined(mingw32_HOST_OS)
 import qualified System.Win32 as Win32
-#else
-import System.Posix (createSymbolicLink)
 #endif
 
-#ifdef mingw32_HOST_OS
-# if defined i386_HOST_ARCH
-#  define WINAPI stdcall
-# elif defined x86_64_HOST_ARCH
-#  define WINAPI ccall
-# else
-#  error unknown architecture
-# endif
-foreign import WINAPI unsafe "windows.h CreateSymbolicLinkW"
-  c_CreateSymbolicLink :: Ptr CWchar -> Ptr CWchar -> CULong -> IO CUChar
-#endif
-
 -- | @'copyPathRecursive' path@ copies an existing file or directory at
 --   /path/ together with its contents and subdirectories.
 --
 --   Warning: mostly untested and might not handle symlinks correctly.
-copyPathRecursive :: FilePath -> FilePath -> IO ()
+copyPathRecursive :: OsPath -> OsPath -> IO ()
 copyPathRecursive source dest =
   (`ioeSetLocation` "copyPathRecursive") `modifyIOError` do
     dirExists <- doesDirectoryExist source
@@ -44,42 +34,77 @@
           [(source </> x, dest </> x) | x <- contents]
       else copyFile source dest
 
-modifyPermissions :: FilePath -> (Permissions -> Permissions) -> IO ()
+modifyPermissions :: OsPath -> (Permissions -> Permissions) -> IO ()
 modifyPermissions path modify = do
   permissions <- getPermissions path
   setPermissions path (modify permissions)
 
-#ifdef mingw32_HOST_OS
-createSymbolicLink :: String -> String -> IO ()
-createSymbolicLink target link =
-  (`ioeSetLocation` "createSymbolicLink") `modifyIOError` do
-    isDir <- (fromIntegral . fromEnum) `fmap`
-             doesDirectoryExist (takeDirectory link </> target)
-    let target' = fixSlash <$> target
-    withCWString target' $ \ pTarget ->
-      withCWString link $ \ pLink -> do
-        status <- c_CreateSymbolicLink pLink pTarget isDir
-        if status == 0
-          then do
-            errCode <- Win32.getLastError
-            if errCode == c_ERROR_PRIVILEGE_NOT_HELD
-              then ioError . (`ioeSetErrorString` permissionErrorMsg) $
-                   mkIOError permissionErrorType "" Nothing (Just link)
-              else Win32.failWith "createSymbolicLink" errCode
-          else return ()
-  where c_ERROR_PRIVILEGE_NOT_HELD = 0x522
-        permissionErrorMsg = "no permission to create symbolic links"
-        fixSlash '/' = '\\'
-        fixSlash c   = c
+-- | On Windows, the handler is called if symbolic links are unsupported or
+-- the user lacks the necessary privileges to create them.  On other
+-- platforms, the handler is never run.
+handleSymlinkUnavail
+  :: IO a                               -- ^ handler
+  -> IO a                               -- ^ arbitrary action
+  -> IO a
+handleSymlinkUnavail _handler action = action
+#if defined(mingw32_HOST_OS)
+  `catchIOError` \ e ->
+    case ioeGetErrorType e of
+      UnsupportedOperation -> _handler
+      _ | isIllegalOperation e || isPermissionError e -> _handler
+      _ -> ioError e
 #endif
 
--- | Attempt to create a symbolic link.  On Windows, this falls back to
---   copying if forbidden due to Group Policies.
-tryCreateSymbolicLink :: FilePath -> FilePath -> IO ()
-tryCreateSymbolicLink target link = createSymbolicLink target link
-#ifdef mingw32_HOST_OS
+-- | Create a hard link on Posix. On Windows, it just copies.
+hardLinkOrCopy :: OsPath -> OsPath -> IO ()
+#if defined(mingw32_HOST_OS)
+hardLinkOrCopy = copyPathRecursive
+#else
+hardLinkOrCopy = createHardLink
+#endif
+
+-- | Create a symbolic link.  On Windows, this falls back to copying if
+-- forbidden by Group Policy or is not supported.  On other platforms, there
+-- is no fallback.  Also, automatically detect if the source is a file or a
+-- directory and create the appropriate type of link.
+symlinkOrCopy :: OsPath -> OsPath -> IO ()
+symlinkOrCopy target link = do
+  let fullTarget = takeDirectory link </> target
+  handleSymlinkUnavail (copyPathRecursive fullTarget link) $ do
+    isDir <- doesDirectoryExist fullTarget
+    (if isDir then createDirectoryLink else createFileLink)
+      (normalise target)
+      link
+
+supportsSymlinks :: IO Bool
+supportsSymlinks = do
+  canCreate <- supportsLinkCreation
+  canDeref <- supportsLinkDeref
+  pure (canCreate && canDeref)
+
+-- | On Windows, test if symbolic link creation is supported and the user has
+-- the necessary privileges to create them.  On other platforms, this always
+-- returns 'True'.
+supportsLinkCreation :: IO Bool
+supportsLinkCreation = do
+  let path = os "_symlink_test.tmp"
+  isSupported <- handleSymlinkUnavail (pure False) $ do
+    True <$ createFileLink path path
+  when isSupported $ do
+    removeFile path
+  pure isSupported
+
+supportsLinkDeref :: IO Bool
+supportsLinkDeref = do
+#if defined(mingw32_HOST_OS)
+    True <$ win32_getFinalPathNameByHandle Win32.nullHANDLE 0
   `catchIOError` \ e ->
-    if isPermissionError e
-    then copyPathRecursive (takeDirectory link </> target) link
-    else ioError e
+    case ioeGetErrorType e of
+      UnsupportedOperation -> pure False
+      _ -> pure True
+#else
+    pure True
 #endif
+
+instance IsString OsString where
+  fromString = os
diff --git a/tests/Util.hs b/tests/Util.hs
--- a/tests/Util.hs
+++ b/tests/Util.hs
@@ -1,10 +1,15 @@
 {-# LANGUAGE BangPatterns #-}
+-- | A rudimentary testing framework
 module Util where
 import Prelude ()
 import System.Directory.Internal.Prelude
-import System.Directory
+import System.Directory.Internal
+import System.Directory.OsPath
 import Data.Time.Clock (NominalDiffTime, UTCTime, diffUTCTime)
-import System.FilePath ((</>), normalise)
+import GHC.Stack (CallStack, HasCallStack, callStack, getCallStack, srcLocFile,
+                  srcLocStartLine)
+import System.Environment (getEnvironment, setEnv, unsetEnv)
+import System.OsPath ((</>), decodeFS, encodeFS, normalise)
 import qualified Data.List as List
 
 modifyIORef' :: IORef a -> (a -> a) -> IO ()
@@ -24,7 +29,7 @@
   result <- timeout (round (1000000 * time)) action
   case result of
     Nothing -> throwIO (userError "timed out")
-    Just x  -> return x
+    Just x  -> pure x
 
 data TestEnv =
   TestEnv
@@ -35,7 +40,7 @@
   }
 
 printInfo :: TestEnv -> [String] -> IO ()
-printInfo TestEnv{testSilent = True}  _   = return ()
+printInfo TestEnv{testSilent = True}  _   = pure ()
 printInfo TestEnv{testSilent = False} msg = do
   putStrLn (List.intercalate ": " msg)
   hFlush stdout
@@ -58,69 +63,72 @@
 checkEither t prefix (Right msg) = printInfo t (prefix <> msg)
 checkEither t prefix (Left  msg) = printFailure t (prefix <> msg)
 
-showContext :: Show a => String -> Integer -> a -> String
-showContext file line context =
-  file <> ":" <> show line <>
+showContext :: Show a => CallStack -> a -> String
+showContext stack context =
+  case getCallStack stack of
+    (_, l) : _ -> srcLocFile l <> ":" <> show (srcLocStartLine l)
+    [] -> "<unknown caller>"
+  <>
   case show context of
     "()" -> ""
     s    -> ":" <> s
 
-inform :: TestEnv -> String -> Integer -> String -> IO ()
-inform t file line msg =
-  printInfo t [showContext file line (), msg]
+inform :: HasCallStack => TestEnv -> String -> IO ()
+inform t msg =
+  printInfo t [showContext callStack (), msg]
 
-expect :: Show a => TestEnv -> String -> Integer -> a -> Bool -> IO ()
-expect t file line context x =
+
+expect :: (HasCallStack, Show a) => TestEnv -> a -> Bool -> IO ()
+expect t context x =
   check t x
-  [showContext file line context]
+  [showContext callStack context]
   ["True"]
   ["False, but True was expected"]
 
-expectEq :: (Eq a, Show a, Show b) =>
-            TestEnv -> String -> Integer -> b -> a -> a -> IO ()
-expectEq t file line context x y =
+expectEq :: (HasCallStack, Eq a, Show a, Show b) =>
+            TestEnv -> b -> a -> a -> IO ()
+expectEq t context x y =
   check t (x == y)
-  [showContext file line context]
+  [showContext callStack context]
   [show x <> " equals "     <> show y]
   [show x <> " is not equal to " <> show y]
 
-expectNe :: (Eq a, Show a, Show b) =>
-            TestEnv -> String -> Integer -> b -> a -> a -> IO ()
-expectNe t file line context x y =
+expectNe :: (HasCallStack, Eq a, Show a, Show b) =>
+            TestEnv -> b -> a -> a -> IO ()
+expectNe t context x y =
   check t (x /= y)
-  [showContext file line context]
+  [showContext callStack context]
   [show x <> " is not equal to " <> show y]
   [show x <> " equals "     <> show y]
 
-expectNear :: (Num a, Ord a, Show a, Show b) =>
-              TestEnv -> String -> Integer -> b -> a -> a -> a -> IO ()
-expectNear t file line context x y diff =
+expectNear :: (HasCallStack, Num a, Ord a, Show a, Show b) =>
+              TestEnv -> b -> a -> a -> a -> IO ()
+expectNear t context x y diff =
   check t (abs (x - y) <= diff)
-  [showContext file line context]
+  [showContext callStack context]
   [show x <> " is near "     <> show y]
   [show x <> " is not near " <> show y]
 
-expectNearTime :: Show a =>
-                  TestEnv -> String -> Integer -> a ->
+expectNearTime :: (HasCallStack, Show a) =>
+                  TestEnv -> a ->
                   UTCTime -> UTCTime -> NominalDiffTime -> IO ()
-expectNearTime t file line context x y diff =
+expectNearTime t context x y diff =
   check t (abs (diffUTCTime x y) <= diff)
-  [showContext file line context]
+  [showContext callStack context]
   [show x <> " is near "     <> show y]
   [show x <> " is not near " <> show y]
 
-expectIOErrorType :: Show a =>
-                     TestEnv -> String -> Integer -> a
-                  -> (IOError -> Bool) -> IO b -> IO ()
-expectIOErrorType t file line context which action = do
+expectIOErrorType :: (HasCallStack, Show a) =>
+                     TestEnv -> a -> (IOError -> Bool) -> IO b -> IO ()
+expectIOErrorType t context which action = do
   result <- try action
-  checkEither t [showContext file line context] $ case result of
+  checkEither t [showContext callStack context] $ case result of
     Left  e | which e   -> Right ["got expected exception (" <> show e <> ")"]
             | otherwise -> Left  ["got wrong exception: ", show e]
     Right _             -> Left  ["did not throw an exception"]
 
 -- | Traverse the directory tree in preorder.
-preprocessPathRecursive :: (FilePath -> IO ()) -> FilePath -> IO ()
+preprocessPathRecursive :: (OsPath -> IO ()) -> OsPath -> IO ()
 preprocessPathRecursive f path = do
   dirExists <- doesDirectoryExist path
   if dirExists
@@ -129,26 +137,76 @@
       f path
       when (not isLink) $ do
         names <- listDirectory path
-        traverse_ (preprocessPathRecursive f) ((path </>) <$> names)
+        for_ ((path </>) <$> names) (preprocessPathRecursive f)
     else do
       f path
 
-withNewDirectory :: Bool -> FilePath -> IO a -> IO a
+withNewDirectory :: Bool -> OsPath -> IO a -> IO a
 withNewDirectory keep dir action = do
   dir' <- makeAbsolute dir
   bracket_ (createDirectoryIfMissing True dir') (cleanup dir') action
-  where cleanup dir' | keep      = return ()
+  where cleanup dir' | keep      = pure ()
                      | otherwise = removePathForcibly dir'
 
-isolateWorkingDirectory :: Bool -> FilePath -> IO a -> IO a
+diffAsc' :: (j -> k -> Ordering)
+         -> (u -> v -> Bool)
+         -> [(j, u)]
+         -> [(k, v)]
+         -> ([(j, u)], [(k, v)])
+diffAsc' cmp eq = go id id
+  where
+    go a b [] [] = (a [], b [])
+    go a b jus [] = go (a . (jus <>)) b [] []
+    go a b [] kvs = go a (b . (kvs <>)) [] []
+    go a b jus@((j, u) : jus') kvs@((k, v) : kvs') =
+      case cmp j k of
+        LT -> go (a . ((j, u) :)) b jus' kvs
+        GT -> go a (b . ((k, v) :)) jus kvs'
+        EQ | eq u v -> go a b jus' kvs'
+           | otherwise -> go (a . ((j, u) :)) (b . ((k, v) :)) jus' kvs'
+
+diffAsc :: (Ord k, Eq v) => [(k, v)] -> [(k, v)] -> ([(k, v)], [(k, v)])
+diffAsc = diffAsc' compare (==)
+
+-- Environment variables may be sensitive, so don't log their values.
+scrubEnv :: (String, String) -> (String, String)
+scrubEnv (k, v)
+  -- Allowlist for nonsensitive variables.
+  | k `elem` ["XDG_CONFIG_HOME"] = (k, v)
+  | otherwise = (k, "<" <> show (length v) <> " chars>")
+
+isolateEnvironment :: IO a -> IO a
+isolateEnvironment = bracket getEnvs setEnvs . const
+  where
+    -- Duplicate environment variables will cause problems for this code.
+    -- https://github.com/haskell/cabal/issues/10718
+    getEnvs = List.sort . filter (\(k, _) -> not (null k)) <$> getEnvironment
+    setEnvs target = do
+      current <- getEnvs
+      let (deletions, insertions) = diffAsc current target
+      updateEnvs deletions insertions
+      new <- getEnvs
+      when (target /= new) $ do
+        let (missing, extraneous) = diffAsc target new
+        throwIO (userError ("isolateEnvironment.setEnvs failed:" <>
+                            " deletions=" <> show (scrubEnv <$> deletions) <>
+                            " insertions=" <> show (scrubEnv <$> insertions) <>
+                            " missing=" <> show (scrubEnv <$> missing) <>
+                            " extraneous=" <> show (scrubEnv <$> extraneous)))
+    updateEnvs deletions insertions = do
+      for_ deletions (unsetEnv . fst)
+      for_ insertions (uncurry setEnv)
+
+isolateWorkingDirectory :: Bool -> OsPath -> IO a -> IO a
 isolateWorkingDirectory keep dir action = do
-  when (normalise dir `List.elem` [".", "./"]) $
+  normalisedDir <- decodeFS (normalise dir)
+  when (normalisedDir `List.elem` [".", "./"]) $
     throwIO (userError ("isolateWorkingDirectory cannot be used " <>
                         "with current directory"))
   dir' <- makeAbsolute dir
   removePathForcibly dir'
-  withNewDirectory keep dir' $
-    withCurrentDirectory dir' $
+  withNewDirectory keep dir' $ do
+    withCurrentDirectory dir' $ do
       action
 
 run :: TestEnv -> String -> (TestEnv -> IO ()) -> IO ()
@@ -156,12 +214,14 @@
   result <- tryAny (action t)
   case result of
     Left  e  -> check t False [name] [] ["exception", show e]
-    Right () -> return ()
+    Right () -> pure ()
 
 isolatedRun :: TestEnv -> String -> (TestEnv -> IO ()) -> IO ()
-isolatedRun t@TestEnv{testKeepDirs = keep} name =
-  run t name .
-  (isolateWorkingDirectory keep ("dist/test-" <> name <> ".tmp") .)
+isolatedRun t@TestEnv{testKeepDirs = keep} name action = do
+  workDir <- encodeFS ("dist-newstyle/tmp/test-" <> name <> ".tmp")
+  run t name (isolate workDir . action)
+  where
+    isolate workDir = isolateEnvironment . isolateWorkingDirectory keep workDir
 
 tryRead :: Read a => String -> Maybe a
 tryRead s =
@@ -199,7 +259,7 @@
           , testArgs     = args
           }
   action t
-  n <- readIORef (counter)
+  n <- readIORef counter
   unless (n == 0) $ do
     putStrLn ("[" <> show n <> " failures]")
     hFlush stdout
diff --git a/tests/WithCurrentDirectory.hs b/tests/WithCurrentDirectory.hs
--- a/tests/WithCurrentDirectory.hs
+++ b/tests/WithCurrentDirectory.hs
@@ -1,22 +1,27 @@
-{-# LANGUAGE CPP #-}
 module WithCurrentDirectory where
-#include "util.inl"
-import System.FilePath ((</>))
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.Internal
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import System.OsPath ((</>))
 import qualified Data.List as List
 
 main :: TestEnv -> IO ()
 main _t = do
   createDirectory dir
   -- Make sure we're starting empty
-  T(expectEq) () [] . List.sort =<< listDirectory dir
+  T.expectEq _t () [] . List.sort =<< listDirectory dir
   cwd <- getCurrentDirectory
-  withCurrentDirectory dir (writeFile testfile contents)
+  withCurrentDirectory dir (writeFile (so testfile) contents)
   -- Are we still in original directory?
-  T(expectEq) () cwd =<< getCurrentDirectory
+  T.expectEq _t () cwd =<< getCurrentDirectory
   -- Did the test file get created?
-  T(expectEq) () [testfile] . List.sort =<< listDirectory dir
+  T.expectEq _t () [testfile] . List.sort =<< listDirectory dir
   -- Does the file contain what we expected to write?
-  T(expectEq) () contents =<< readFile (dir </> testfile)
+  T.expectEq _t () contents =<< readFile (so (dir </> testfile))
   where
     testfile = "testfile"
     contents = "some data\n"
diff --git a/tests/Xdg.hs b/tests/Xdg.hs
new file mode 100644
--- /dev/null
+++ b/tests/Xdg.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE CPP #-}
+module Xdg where
+import Prelude ()
+import System.Directory.Internal.Prelude
+import System.Directory.OsPath
+import TestUtils ()
+import Util (TestEnv)
+import qualified Util as T
+import qualified Data.List as List
+import System.Environment (setEnv, unsetEnv)
+import System.FilePath (searchPathSeparator)
+#if !defined(mingw32_HOST_OS)
+import System.OsPath ((</>))
+#endif
+
+main :: TestEnv -> IO ()
+main _t = do
+
+  -- smoke tests
+  _ <- getXdgDirectoryList XdgDataDirs
+  _ <- getXdgDirectoryList XdgConfigDirs
+
+  T.expect _t () True -- avoid warnings about redundant imports
+
+  -- setEnv, unsetEnv require base 4.7.0.0+
+#if !defined(mingw32_HOST_OS)
+  unsetEnv "XDG_CONFIG_HOME"
+  home <- getHomeDirectory
+  T.expectEq _t () (home </> ".config/mow") =<< getXdgDirectory XdgConfig "mow"
+#endif
+
+  -- unset variables, so env doesn't affect test running
+  unsetEnv "XDG_DATA_HOME"
+  unsetEnv "XDG_CONFIG_HOME"
+  unsetEnv "XDG_CACHE_HOME"
+  unsetEnv "XDG_STATE_HOME"
+  xdgData   <- getXdgDirectory XdgData   "ff"
+  xdgConfig <- getXdgDirectory XdgConfig "oo"
+  xdgCache  <- getXdgDirectory XdgCache  "rk"
+  xdgState  <- getXdgDirectory XdgState  "aa"
+
+  -- non-absolute paths are ignored, and the fallback is used
+  setEnv "XDG_DATA_HOME"   "ar"
+  setEnv "XDG_CONFIG_HOME" "aw"
+  setEnv "XDG_CACHE_HOME"  "ba"
+  setEnv "XDG_STATE_HOME"  "uw"
+  T.expectEq _t () xdgData   =<< getXdgDirectory XdgData   "ff"
+  T.expectEq _t () xdgConfig =<< getXdgDirectory XdgConfig "oo"
+  T.expectEq _t () xdgCache  =<< getXdgDirectory XdgCache  "rk"
+  T.expectEq _t () xdgState  =<< getXdgDirectory XdgState  "aa"
+
+  unsetEnv "XDG_CONFIG_DIRS"
+  unsetEnv "XDG_DATA_DIRS"
+  _xdgConfigDirs <- getXdgDirectoryList XdgConfigDirs
+  _xdgDataDirs <- getXdgDirectoryList XdgDataDirs
+
+#if !defined(mingw32_HOST_OS)
+  T.expectEq _t () ["/etc/xdg"] _xdgConfigDirs
+  T.expectEq _t () ["/usr/local/share/", "/usr/share/"] _xdgDataDirs
+#endif
+
+  setEnv "XDG_DATA_DIRS" (List.intercalate [searchPathSeparator] ["/a", "/b"])
+  setEnv "XDG_CONFIG_DIRS" (List.intercalate [searchPathSeparator] ["/c", "/d"])
+  T.expectEq _t () ["/a", "/b"] =<< getXdgDirectoryList XdgDataDirs
+  T.expectEq _t () ["/c", "/d"] =<< getXdgDirectoryList XdgConfigDirs
diff --git a/tests/util.inl b/tests/util.inl
deleted file mode 100644
--- a/tests/util.inl
+++ /dev/null
@@ -1,7 +0,0 @@
-#define T(f) (T.f _t __FILE__ __LINE__)
-
-import Prelude ()
-import System.Directory.Internal.Prelude
-import System.Directory
-import Util (TestEnv)
-import qualified Util as T
