diff --git a/DBDirect.hs b/DBDirect.hs
new file mode 100644
--- /dev/null
+++ b/DBDirect.hs
@@ -0,0 +1,5 @@
+import Database.HaskellDB.FlatDB
+import Database.HaskellDB.DBDirect
+
+main :: IO ()
+main = dbdirect driver
diff --git a/Database/HaskellDB/FlatDB.hs b/Database/HaskellDB/FlatDB.hs
--- a/Database/HaskellDB/FlatDB.hs
+++ b/Database/HaskellDB/FlatDB.hs
@@ -16,15 +16,18 @@
                                   withFlatDB, newDB) where
 
 import Database.HaskellDB.Database
-import Database.HaskellDB.HDBRec
 import Database.HaskellDB.FieldType
 import Database.HaskellDB.PrimQuery
 import Database.HaskellDB.Query	hiding (isNull, union, intersect)
 import Database.HaskellDB.DriverAPI
+import Database.HaskellDB (Record)
 
+import Control.Exception (bracket)
 import Control.Monad
+import Control.Monad.Error ()
 import Control.Monad.Trans
 import Data.Bits
+import Data.Function (on)
 import Data.IORef
 import Data.Map (Map)
 import qualified Data.Map as Map
@@ -67,11 +70,12 @@
 flatDBConnectOpts opts f = do [a] <- getOptions ["filepath"] opts
                               withFlatDB a f
 
+-- FIXME: this is full of race conditions
 withFlatDB :: MonadIO m => FilePath -> (Database -> m a) -> m a
 withFlatDB f m = 
     do e <- liftIO $ doesFileExist f
        when (not e) $ liftIO $ newDB f
-       db <- liftIO $ readDB f
+       db <- liftIO $ fileReadDB f
        dbr <- liftIO $ newIORef db
        x <- m (flatDatabase dbr)
        db' <- liftIO $ readIORef dbr
@@ -106,28 +110,37 @@
 	       dbDropTable    = \x -> modifyDB db $ flatDropTable x
 	     }
 
+fileReadDB :: FilePath -> IO FlatDB
+fileReadDB f = openFile f ReadMode >>= hReadDB
 
-readDB :: FilePath -> IO FlatDB
-readDB f = do c <- readFile f
-              case reads c of
-                [] -> err $ "parse error"
-                [(x,[])] -> return x
-                [(_,_)]  -> err $ "junk at end"
-                _  -> fail $ "ambiguous parse"
-    where err e = fail $ "FlatDB error when reading " ++ show f 
-                         ++ ": " ++ e
+hReadDB :: Handle -> IO FlatDB
+hReadDB h = 
+    do c <- hGetContents h
+       case readDB c of
+           Left err ->
+               fail $ "FlatDB error when reading " ++ show h
+                        ++ ": " ++ err
+           Right db -> return db
 
-writeDB :: FilePath -> FlatDB -> IO ()
-writeDB f db = do h <- openFile f WriteMode
-                  hWriteDB h db
-                  hClose h
+fileWriteDB :: FilePath -> FlatDB -> IO ()
+fileWriteDB f db = bracket (openFile f WriteMode) hClose (flip hWriteDB db) 
 
 hWriteDB :: Handle -> FlatDB -> IO ()
-hWriteDB h db = hPutStr h $ show db
+hWriteDB h db = hPutStr h $ showDB db
 
 newDB :: FilePath -> IO ()
-newDB f = writeDB f emptyDB
+newDB f = fileWriteDB f emptyDB
 
+showDB :: FlatDB -> String
+showDB = show . Map.toList 
+
+readDB :: Monad m => String -> m FlatDB
+readDB c = case reads c of
+                []       -> fail "parse error"
+                [(x,[])] -> return $ Map.fromList x
+                [(_,_)]  -> fail "junk at end"
+                _        -> fail "ambiguous parse"
+
 -- Relations
 
 -- FIXME: make distinct
@@ -196,6 +209,10 @@
                           | otherwise = map (\g -> fst (head g) ++ [(n,evalAggr (map snd g) e) | (n,e) <- abs]) rps2
            Restrict p x -> relFilter (\r -> toBool (evalExpr r p)) t
                where t = e x
+           Group gs x -> FlatRel { relSchema = s, relRows = rs' }
+               where FlatRel { relSchema = s, relRows = rs } = e x
+                     -- FIXME: BUG: what if groups are not contiguous?
+                     rs' = map (fst . head) $ groupBy ((==) `on` snd) [(r,evalBinds r gs) | r <- rs]
            Binary op x1 x2 ->
                case op of
                    Times -> FlatRel { relSchema = s1 ++ s2, -- FIXME: assert s1, s2 disjoint
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 1999 Daan Leijen, daan@cs.uu.nl
+Copyright (c) 2003-2004 The HaskellDB development team
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the names of the copyright holders nor the names of the
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/haskelldb-flat.cabal b/haskelldb-flat.cabal
--- a/haskelldb-flat.cabal
+++ b/haskelldb-flat.cabal
@@ -1,23 +1,33 @@
 Name: haskelldb-flat
-Version: 0.10
+Version: 1.0.1
+Cabal-version: >= 1.6
+Build-type: Simple
+Homepage: https://github.com/m4dc4p/haskelldb
+Maintainer: Maintainer: haskelldb-users@lists.sourceforge.net
+License-file: LICENSE
 Copyright: Bjorn Bringert
-Maintainer: bjorn@bringert.net
 Author: Bjorn Bringert
 License: BSD3
-build-depends: 
-  haskell98, 
-  base, 
-  mtl, 
-  haskelldb==0.10
-Extensions: 
 Synopsis: An experimental HaskellDB back-end in pure Haskell (no SQL)
 Description:
   This is a very experimental HaskellDB back-end which is written in pure Haskell
   and doesn't use SQL. It stores the database in a file. Using this with
   concurrent writes leads to data loss. This back-end does not support transactions.
-Exposed-Modules: Database.HaskellDB.FlatDB
-ghc-options: -O2
+Category: Database
 
-Executable:  flatdb-create
-Main-Is:     tools/flatdb-create.hs
-ghc-options: -O2 -Wall
+Flag split-base
+
+Library
+  Build-depends: mtl, haskelldb >= 1 && < 2
+  if flag(split-base)
+    Build-depends: base >= 3 && < 5, containers, old-time >= 1 && < 2, directory >= 1 && < 2
+  else
+    Build-depends: base < 3.0
+  Exposed-Modules: Database.HaskellDB.FlatDB
+
+Executable DBDirect-flat
+  Main-is: DBDirect.hs
+
+Source-repository head
+  Type:       git
+  Location:   https://github.com/m4dc4p/haskelldb
diff --git a/tools/flatdb-create.hs b/tools/flatdb-create.hs
deleted file mode 100644
--- a/tools/flatdb-create.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-import Database.HaskellDB.FlatDB
-
-import System.Environment
-import System.IO
-
-main :: IO ()
-main = do args <- getArgs
-          case args of
-            [f] -> newDB f
-            _   -> hPutStrLn stderr "Usage: flatdb-create <file>"
