    {-# LANGUAGE Rank2Types, TypeSynonymInstances, DeriveDataTypeable, FlexibleInstances #-}
    {- |
       Module      : Data.FileStore.Types
       Copyright   : Copyright (C) 2009 John MacFarlane
       License     : BSD 3

       Maintainer  : John MacFarlane <jgm@berkeley.edu>
       Stability   : alpha
       Portability : GHC 6.10 required

       Type definitions for "Data.FileStore".
    -}

    module Data.FileStore.Types
               ( RevisionId
               , Resource(..)
               , Author(..)
               , Change(..)
               , Description
               , Revision(..)
               , Contents(..)
               , TimeRange(..)
               , MergeInfo(..)
               , FileStoreError(..)
               , SearchMatch(..)
               , SearchQuery(..)
               , defaultSearchQuery
               , UTCTime
               , FileStore (..) )

    where
    import Data.ByteString.Lazy (ByteString)
    import Data.Typeable
    import Data.ByteString.Lazy.UTF8 (toString, fromString)
    import Data.Time (UTCTime)
    import Control.Exception (Exception)

    type RevisionId   = String

    data Resource = FSFile FilePath
                  | FSDirectory FilePath
                  deriving (Int -> Resource -> ShowS
    [Resource] -> ShowS
    Resource -> String
    (Int -> Resource -> ShowS)
    -> (Resource -> String) -> ([Resource] -> ShowS) -> Show Resource
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Resource -> ShowS
    showsPrec :: Int -> Resource -> ShowS
    $cshow :: Resource -> String
    show :: Resource -> String
    $cshowList :: [Resource] -> ShowS
    showList :: [Resource] -> ShowS
    Show, ReadPrec [Resource]
    ReadPrec Resource
    Int -> ReadS Resource
    ReadS [Resource]
    (Int -> ReadS Resource)
    -> ReadS [Resource]
    -> ReadPrec Resource
    -> ReadPrec [Resource]
    -> Read Resource
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Resource
    readsPrec :: Int -> ReadS Resource
    $creadList :: ReadS [Resource]
    readList :: ReadS [Resource]
    $creadPrec :: ReadPrec Resource
    readPrec :: ReadPrec Resource
    $creadListPrec :: ReadPrec [Resource]
    readListPrec :: ReadPrec [Resource]
    Read, Resource -> Resource -> Bool
    (Resource -> Resource -> Bool)
    -> (Resource -> Resource -> Bool) -> Eq Resource
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Resource -> Resource -> Bool
    == :: Resource -> Resource -> Bool
    $c/= :: Resource -> Resource -> Bool
    /= :: Resource -> Resource -> Bool
    Eq, Typeable, Eq Resource
    Eq Resource
    -> (Resource -> Resource -> Ordering)
    -> (Resource -> Resource -> Bool)
    -> (Resource -> Resource -> Bool)
    -> (Resource -> Resource -> Bool)
    -> (Resource -> Resource -> Bool)
    -> (Resource -> Resource -> Resource)
    -> (Resource -> Resource -> Resource)
    -> Ord Resource
    Resource -> Resource -> Bool
    Resource -> Resource -> Ordering
    Resource -> Resource -> Resource
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Resource -> Resource -> Ordering
    compare :: Resource -> Resource -> Ordering
    $c< :: Resource -> Resource -> Bool
    < :: Resource -> Resource -> Bool
    $c<= :: Resource -> Resource -> Bool
    <= :: Resource -> Resource -> Bool
    $c> :: Resource -> Resource -> Bool
    > :: Resource -> Resource -> Bool
    $c>= :: Resource -> Resource -> Bool
    >= :: Resource -> Resource -> Bool
    $cmax :: Resource -> Resource -> Resource
    max :: Resource -> Resource -> Resource
    $cmin :: Resource -> Resource -> Resource
    min :: Resource -> Resource -> Resource
    Ord)

    data Author =
      Author {
        Author -> String
    authorName  :: String
      , Author -> String
    authorEmail :: String
      } deriving (Int -> Author -> ShowS
    [Author] -> ShowS
    Author -> String
    (Int -> Author -> ShowS)
    -> (Author -> String) -> ([Author] -> ShowS) -> Show Author
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Author -> ShowS
    showsPrec :: Int -> Author -> ShowS
    $cshow :: Author -> String
    show :: Author -> String
    $cshowList :: [Author] -> ShowS
    showList :: [Author] -> ShowS
    Show, ReadPrec [Author]
    ReadPrec Author
    Int -> ReadS Author
    ReadS [Author]
    (Int -> ReadS Author)
    -> ReadS [Author]
    -> ReadPrec Author
    -> ReadPrec [Author]
    -> Read Author
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Author
    readsPrec :: Int -> ReadS Author
    $creadList :: ReadS [Author]
    readList :: ReadS [Author]
    $creadPrec :: ReadPrec Author
    readPrec :: ReadPrec Author
    $creadListPrec :: ReadPrec [Author]
    readListPrec :: ReadPrec [Author]
    Read, Author -> Author -> Bool
    (Author -> Author -> Bool)
    -> (Author -> Author -> Bool) -> Eq Author
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Author -> Author -> Bool
    == :: Author -> Author -> Bool
    $c/= :: Author -> Author -> Bool
    /= :: Author -> Author -> Bool
    Eq, Typeable)

    data Change =
        Added FilePath
      | Deleted FilePath
      | Modified FilePath
      deriving (Int -> Change -> ShowS
    [Change] -> ShowS
    Change -> String
    (Int -> Change -> ShowS)
    -> (Change -> String) -> ([Change] -> ShowS) -> Show Change
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Change -> ShowS
    showsPrec :: Int -> Change -> ShowS
    $cshow :: Change -> String
    show :: Change -> String
    $cshowList :: [Change] -> ShowS
    showList :: [Change] -> ShowS
    Show, ReadPrec [Change]
    ReadPrec Change
    Int -> ReadS Change
    ReadS [Change]
    (Int -> ReadS Change)
    -> ReadS [Change]
    -> ReadPrec Change
    -> ReadPrec [Change]
    -> Read Change
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Change
    readsPrec :: Int -> ReadS Change
    $creadList :: ReadS [Change]
    readList :: ReadS [Change]
    $creadPrec :: ReadPrec Change
    readPrec :: ReadPrec Change
    $creadListPrec :: ReadPrec [Change]
    readListPrec :: ReadPrec [Change]
    Read, Change -> Change -> Bool
    (Change -> Change -> Bool)
    -> (Change -> Change -> Bool) -> Eq Change
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Change -> Change -> Bool
    == :: Change -> Change -> Bool
    $c/= :: Change -> Change -> Bool
    /= :: Change -> Change -> Bool
    Eq, Typeable)

    type Description = String

    data Revision =
      Revision {
        Revision -> String
    revId          :: RevisionId
      , Revision -> UTCTime
    revDateTime    :: UTCTime
      , Revision -> Author
    revAuthor      :: Author
      , Revision -> String
    revDescription :: Description
      , Revision -> [Change]
    revChanges     :: [Change]
      } deriving (Int -> Revision -> ShowS
    [Revision] -> ShowS
    Revision -> String
    (Int -> Revision -> ShowS)
    -> (Revision -> String) -> ([Revision] -> ShowS) -> Show Revision
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Revision -> ShowS
    showsPrec :: Int -> Revision -> ShowS
    $cshow :: Revision -> String
    show :: Revision -> String
    $cshowList :: [Revision] -> ShowS
    showList :: [Revision] -> ShowS
    Show, ReadPrec [Revision]
    ReadPrec Revision
    Int -> ReadS Revision
    ReadS [Revision]
    (Int -> ReadS Revision)
    -> ReadS [Revision]
    -> ReadPrec Revision
    -> ReadPrec [Revision]
    -> Read Revision
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS Revision
    readsPrec :: Int -> ReadS Revision
    $creadList :: ReadS [Revision]
    readList :: ReadS [Revision]
    $creadPrec :: ReadPrec Revision
    readPrec :: ReadPrec Revision
    $creadListPrec :: ReadPrec [Revision]
    readListPrec :: ReadPrec [Revision]
    Read, Revision -> Revision -> Bool
    (Revision -> Revision -> Bool)
    -> (Revision -> Revision -> Bool) -> Eq Revision
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Revision -> Revision -> Bool
    == :: Revision -> Revision -> Bool
    $c/= :: Revision -> Revision -> Bool
    /= :: Revision -> Revision -> Bool
    Eq, Typeable)

    class Contents a where
      fromByteString :: ByteString -> a
      toByteString   :: a -> ByteString

    instance Contents ByteString where
      toByteString :: ByteString -> ByteString
    toByteString = ByteString -> ByteString
    forall a. a -> a
    id
      fromByteString :: ByteString -> ByteString
    fromByteString = ByteString -> ByteString
    forall a. a -> a
    id

    instance Contents String where
      toByteString :: String -> ByteString
    toByteString   = String -> ByteString
    fromString
      fromByteString :: ByteString -> String
    fromByteString = ByteString -> String
    toString

    data TimeRange =
      TimeRange {
        TimeRange -> Maybe UTCTime
    timeFrom :: Maybe UTCTime  -- ^ @Nothing@ means no lower bound
      , TimeRange -> Maybe UTCTime
    timeTo   :: Maybe UTCTime  -- ^ @Nothing@ means no upper bound
      } deriving (Int -> TimeRange -> ShowS
    [TimeRange] -> ShowS
    TimeRange -> String
    (Int -> TimeRange -> ShowS)
    -> (TimeRange -> String)
    -> ([TimeRange] -> ShowS)
    -> Show TimeRange
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> TimeRange -> ShowS
    showsPrec :: Int -> TimeRange -> ShowS
    $cshow :: TimeRange -> String
    show :: TimeRange -> String
    $cshowList :: [TimeRange] -> ShowS
    showList :: [TimeRange] -> ShowS
    Show, ReadPrec [TimeRange]
    ReadPrec TimeRange
    Int -> ReadS TimeRange
    ReadS [TimeRange]
    (Int -> ReadS TimeRange)
    -> ReadS [TimeRange]
    -> ReadPrec TimeRange
    -> ReadPrec [TimeRange]
    -> Read TimeRange
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS TimeRange
    readsPrec :: Int -> ReadS TimeRange
    $creadList :: ReadS [TimeRange]
    readList :: ReadS [TimeRange]
    $creadPrec :: ReadPrec TimeRange
    readPrec :: ReadPrec TimeRange
    $creadListPrec :: ReadPrec [TimeRange]
    readListPrec :: ReadPrec [TimeRange]
    Read, TimeRange -> TimeRange -> Bool
    (TimeRange -> TimeRange -> Bool)
    -> (TimeRange -> TimeRange -> Bool) -> Eq TimeRange
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TimeRange -> TimeRange -> Bool
    == :: TimeRange -> TimeRange -> Bool
    $c/= :: TimeRange -> TimeRange -> Bool
    /= :: TimeRange -> TimeRange -> Bool
    Eq, Typeable)

    data MergeInfo =
      MergeInfo {
        MergeInfo -> Revision
    mergeRevision  :: Revision   -- ^ The revision w/ which changes were merged
      , MergeInfo -> Bool
    mergeConflicts :: Bool       -- ^ @True@ if there were merge conflicts
      , MergeInfo -> String
    mergeText      :: String     -- ^ The merged text, w/ conflict markers
      } deriving (Int -> MergeInfo -> ShowS
    [MergeInfo] -> ShowS
    MergeInfo -> String
    (Int -> MergeInfo -> ShowS)
    -> (MergeInfo -> String)
    -> ([MergeInfo] -> ShowS)
    -> Show MergeInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> MergeInfo -> ShowS
    showsPrec :: Int -> MergeInfo -> ShowS
    $cshow :: MergeInfo -> String
    show :: MergeInfo -> String
    $cshowList :: [MergeInfo] -> ShowS
    showList :: [MergeInfo] -> ShowS
    Show, ReadPrec [MergeInfo]
    ReadPrec MergeInfo
    Int -> ReadS MergeInfo
    ReadS [MergeInfo]
    (Int -> ReadS MergeInfo)
    -> ReadS [MergeInfo]
    -> ReadPrec MergeInfo
    -> ReadPrec [MergeInfo]
    -> Read MergeInfo
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS MergeInfo
    readsPrec :: Int -> ReadS MergeInfo
    $creadList :: ReadS [MergeInfo]
    readList :: ReadS [MergeInfo]
    $creadPrec :: ReadPrec MergeInfo
    readPrec :: ReadPrec MergeInfo
    $creadListPrec :: ReadPrec [MergeInfo]
    readListPrec :: ReadPrec [MergeInfo]
    Read, MergeInfo -> MergeInfo -> Bool
    (MergeInfo -> MergeInfo -> Bool)
    -> (MergeInfo -> MergeInfo -> Bool) -> Eq MergeInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: MergeInfo -> MergeInfo -> Bool
    == :: MergeInfo -> MergeInfo -> Bool
    $c/= :: MergeInfo -> MergeInfo -> Bool
    /= :: MergeInfo -> MergeInfo -> Bool
    Eq, Typeable)

    data FileStoreError =
        RepositoryExists             -- ^ Tried to initialize a repo that exists
      | ResourceExists               -- ^ Tried to create a resource that exists
      | NotFound                     -- ^ Requested resource was not found
      | IllegalResourceName          -- ^ The specified resource name is illegal
      | Unchanged                    -- ^ The resource was not modified,
                                     --   because the contents were unchanged
      | UnsupportedOperation
      | NoMaxCount                   -- ^ The darcs version used does not support
                                     --   --max-count
      | UnknownError String
      deriving (ReadPrec [FileStoreError]
    ReadPrec FileStoreError
    Int -> ReadS FileStoreError
    ReadS [FileStoreError]
    (Int -> ReadS FileStoreError)
    -> ReadS [FileStoreError]
    -> ReadPrec FileStoreError
    -> ReadPrec [FileStoreError]
    -> Read FileStoreError
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS FileStoreError
    readsPrec :: Int -> ReadS FileStoreError
    $creadList :: ReadS [FileStoreError]
    readList :: ReadS [FileStoreError]
    $creadPrec :: ReadPrec FileStoreError
    readPrec :: ReadPrec FileStoreError
    $creadListPrec :: ReadPrec [FileStoreError]
    readListPrec :: ReadPrec [FileStoreError]
    Read, FileStoreError -> FileStoreError -> Bool
    (FileStoreError -> FileStoreError -> Bool)
    -> (FileStoreError -> FileStoreError -> Bool) -> Eq FileStoreError
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FileStoreError -> FileStoreError -> Bool
    == :: FileStoreError -> FileStoreError -> Bool
    $c/= :: FileStoreError -> FileStoreError -> Bool
    /= :: FileStoreError -> FileStoreError -> Bool
    Eq, Typeable)

    instance Show FileStoreError where
      show :: FileStoreError -> String
    show FileStoreError
    RepositoryExists      = String
    "RepositoryExists"
      show FileStoreError
    ResourceExists        = String
    "ResourceExists"
      show FileStoreError
    NotFound              = String
    "NotFound"
      show FileStoreError
    IllegalResourceName   = String
    "IllegalResourceName"
      show FileStoreError
    Unchanged             = String
    "Unchanged"
      show FileStoreError
    UnsupportedOperation  = String
    "UnsupportedOperation"
      show FileStoreError
    NoMaxCount            = String
    "NoMaxCount:\n"
        String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "filestore was compiled with the maxcount flag, but your version of\n"
        String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "darcs does not support the --max-count option.  You should either\n"
        String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "upgrade to darcs >= 2.3.0 (recommended) or compile filestore without\n"
        String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "the maxcount flag (cabal install filestore -f-maxcount)."
      show (UnknownError String
    s)      = String
    "UnknownError: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    s

    instance Exception FileStoreError

    data SearchQuery =
      SearchQuery {
        SearchQuery -> [String]
    queryPatterns    :: [String] -- ^ Patterns to match
      , SearchQuery -> Bool
    queryWholeWords  :: Bool     -- ^ Match patterns only with whole words?
      , SearchQuery -> Bool
    queryMatchAll    :: Bool     -- ^ Return matches only from files in which
                                     --   all patterns match?
      , SearchQuery -> Bool
    queryIgnoreCase  :: Bool     -- ^ Make matches case-insensitive?
      } deriving (Int -> SearchQuery -> ShowS
    [SearchQuery] -> ShowS
    SearchQuery -> String
    (Int -> SearchQuery -> ShowS)
    -> (SearchQuery -> String)
    -> ([SearchQuery] -> ShowS)
    -> Show SearchQuery
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SearchQuery -> ShowS
    showsPrec :: Int -> SearchQuery -> ShowS
    $cshow :: SearchQuery -> String
    show :: SearchQuery -> String
    $cshowList :: [SearchQuery] -> ShowS
    showList :: [SearchQuery] -> ShowS
    Show, ReadPrec [SearchQuery]
    ReadPrec SearchQuery
    Int -> ReadS SearchQuery
    ReadS [SearchQuery]
    (Int -> ReadS SearchQuery)
    -> ReadS [SearchQuery]
    -> ReadPrec SearchQuery
    -> ReadPrec [SearchQuery]
    -> Read SearchQuery
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS SearchQuery
    readsPrec :: Int -> ReadS SearchQuery
    $creadList :: ReadS [SearchQuery]
    readList :: ReadS [SearchQuery]
    $creadPrec :: ReadPrec SearchQuery
    readPrec :: ReadPrec SearchQuery
    $creadListPrec :: ReadPrec [SearchQuery]
    readListPrec :: ReadPrec [SearchQuery]
    Read, SearchQuery -> SearchQuery -> Bool
    (SearchQuery -> SearchQuery -> Bool)
    -> (SearchQuery -> SearchQuery -> Bool) -> Eq SearchQuery
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SearchQuery -> SearchQuery -> Bool
    == :: SearchQuery -> SearchQuery -> Bool
    $c/= :: SearchQuery -> SearchQuery -> Bool
    /= :: SearchQuery -> SearchQuery -> Bool
    Eq, Typeable)

    defaultSearchQuery :: SearchQuery
    defaultSearchQuery :: SearchQuery
    defaultSearchQuery = SearchQuery {
         queryPatterns :: [String]
    queryPatterns   = []
       , queryWholeWords :: Bool
    queryWholeWords = Bool
    True
       , queryMatchAll :: Bool
    queryMatchAll   = Bool
    True
       , queryIgnoreCase :: Bool
    queryIgnoreCase = Bool
    True
       }

    data SearchMatch =
      SearchMatch {
        SearchMatch -> String
    matchResourceName :: FilePath
      , SearchMatch -> Integer
    matchLineNumber   :: Integer
      , SearchMatch -> String
    matchLine         :: String
      } deriving (Int -> SearchMatch -> ShowS
    [SearchMatch] -> ShowS
    SearchMatch -> String
    (Int -> SearchMatch -> ShowS)
    -> (SearchMatch -> String)
    -> ([SearchMatch] -> ShowS)
    -> Show SearchMatch
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SearchMatch -> ShowS
    showsPrec :: Int -> SearchMatch -> ShowS
    $cshow :: SearchMatch -> String
    show :: SearchMatch -> String
    $cshowList :: [SearchMatch] -> ShowS
    showList :: [SearchMatch] -> ShowS
    Show, ReadPrec [SearchMatch]
    ReadPrec SearchMatch
    Int -> ReadS SearchMatch
    ReadS [SearchMatch]
    (Int -> ReadS SearchMatch)
    -> ReadS [SearchMatch]
    -> ReadPrec SearchMatch
    -> ReadPrec [SearchMatch]
    -> Read SearchMatch
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS SearchMatch
    readsPrec :: Int -> ReadS SearchMatch
    $creadList :: ReadS [SearchMatch]
    readList :: ReadS [SearchMatch]
    $creadPrec :: ReadPrec SearchMatch
    readPrec :: ReadPrec SearchMatch
    $creadListPrec :: ReadPrec [SearchMatch]
    readListPrec :: ReadPrec [SearchMatch]
    Read, SearchMatch -> SearchMatch -> Bool
    (SearchMatch -> SearchMatch -> Bool)
    -> (SearchMatch -> SearchMatch -> Bool) -> Eq SearchMatch
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SearchMatch -> SearchMatch -> Bool
    == :: SearchMatch -> SearchMatch -> Bool
    $c/= :: SearchMatch -> SearchMatch -> Bool
    /= :: SearchMatch -> SearchMatch -> Bool
    Eq, Typeable)

    -- | A versioning filestore, which can be implemented using the
    -- file system, a database, or revision-control software.
    data FileStore = FileStore {

        -- | Initialize a new filestore.
        FileStore -> IO ()
    initialize     :: IO ()

        -- | Save contents in the filestore.
      , FileStore
    -> forall a. Contents a => String -> Author -> String -> a -> IO ()
    save           :: forall a . Contents a
                       => FilePath          -- Resource to save.
                       -> Author            --  Author of change.
                       -> Description       --  Description of change.
                       -> a                 --  New contents of resource.
                       -> IO ()

        -- | Retrieve the contents of the named resource.
      , FileStore -> forall a. Contents a => String -> Maybe String -> IO a
    retrieve       :: forall a . Contents a
                       => FilePath          -- Resource to retrieve.
                       -> Maybe RevisionId  -- @Just@ a particular revision ID,
                                            -- or @Nothing@ for latest
                       -> IO a

        -- | Delete a named resource, providing author and log message.
      , FileStore -> String -> Author -> String -> IO ()
    delete         :: FilePath          -- Resource to delete.
                       -> Author            -- Author of change.
                       -> Description       -- Description of change.
                       -> IO ()

        -- | Rename a resource, providing author and log message.
      , FileStore -> String -> String -> Author -> String -> IO ()
    rename         :: FilePath          -- Resource original name.
                       -> FilePath          -- Resource new name.
                       -> Author            -- Author of change.
                       -> Description       -- Description of change.
                       -> IO ()

        -- | Get history for a list of named resources in a (possibly openended)
        -- time range. If the list is empty, history for all resources will
        -- be returned. If the TimeRange is 2 Nothings, history for all dates will be returned.
      , FileStore -> [String] -> TimeRange -> Maybe Int -> IO [Revision]
    history        :: [FilePath]        -- List of resources to get history for
                                            -- or @[]@ for all.
                       -> TimeRange         -- Time range in which to get history.
                       -> Maybe Int         -- Maybe max number of entries.
                       -> IO [Revision]

        -- | Return the revision ID of the latest change for a resource.
        -- Raises 'NotFound' if the resource is not found.
      , FileStore -> String -> IO String
    latest         :: FilePath          -- Resource to get revision ID for.
                       -> IO RevisionId

        -- | Return information about a revision, given the ID.
        -- Raises 'NotFound' if there is no such revision.
      , FileStore -> String -> IO Revision
    revision       :: RevisionId        -- Revision ID to get information for.
                       -> IO Revision

        -- | Return a list of resources in the filestore.
      , FileStore -> IO [String]
    index          :: IO [FilePath]

      -- | Return a list of resources in a directory of the filestore.
      , FileStore -> String -> IO [Resource]
    directory      :: FilePath          -- Directory to list (empty for root)
                       -> IO [Resource]

        -- | @True@ if the revision IDs match, in the sense that the
        -- can be treated as specifying the same revision.
      , FileStore -> String -> String -> Bool
    idsMatch       :: RevisionId
                       -> RevisionId
                       -> Bool

      -- | Search the filestore for patterns.
      , FileStore -> SearchQuery -> IO [SearchMatch]
    search         :: SearchQuery
                       -> IO [SearchMatch]

      }