diff --git a/README b/README
deleted file mode 100644
--- a/README
+++ /dev/null
@@ -1,133 +0,0 @@
-Fibon in a Flash
-===================================================================
-    $ git clone git://github.com/dmpots/fibon.git
-    $ cd fibon
-    $ git submodule update --init benchmarks
-    $ cabal configure && cabal build
-    $ ./dist/build/fibon-run/fibon-run
-
-Introduction
-===================================================================
-Fibon is a set of tools for running and analysing benchmarks in
-Haskell. Most importantly, it includes a set of default benchmarks
-taken from the [Hackage][1] open source repository.
-
-Benchmarks
-------------------
-Fibon makes it easy to use either the fibon benchmarks or your own
-set of benchmarks. Benchmarks are stored in the
-`benchmarks/Fibon/Benchmarks` directory. This directory is setup as
-a [git submodule][2] which means you can easily grab the standard
-suite or use a suite kept under your own source control.
-
-Benchmark Groups
-------------------
-Benchamarks named and organized into groups based on the filesystem
-organization. For example, a benchmark in the directory
-`benchmarks/Fibon/Benchmarks/Hackage/Agum` will have the name `Agum`
-an be in the benchmark group `Hackage`.
-
-Executables
-------------------
-The fibon package builds three tools
-  1. `fibon-run` - runs the benchmarks
-  2. `fibon-analyze` - analyzes the results of a run
-  2. `fibon-init` - utilty used when adding new benchmarks
-
-Size and Tune
-------------------
-Fibon benchmarks can be run with two different input sizes: `Test` and
-`Ref`. The `Test` size is useful to make sure that a benchmark can
-run successsfully, but will not give meaningful timings.
-
-Fibon benchmarks can be run under two different tune settings (e.g.
-compiler optimization settings). The `Base` and `Peak` settings can
-be configured anyway you want to make the desired comparison.
-
-Directory Structure
---------------------
-Source directories
-    ./benchmarks -- benchmark code
-    ./config     -- config files
-    ./lib        -- common files used by several executables
-    ./tools      -- source code for executables
-
-Working directories
-    ./log        -- logging output from benchmark runs
-    ./run        -- working directory for benchmark runs
-
-Getting the Benchmarks
-===================================================================
-The benchmarks are kept in a separate repository as a [git
-submodule][2]. You can get the fibon benchmarks by updating the
-submodule from within your fibon working directory
-
-    $ git submodule update --init benchmarks
-
-This will checkout the benchmarks from the fibon-benchmarks
-repository and place them in your working copy.
-
-Running Benchmarks
-===================================================================
-The available benchmarks and configurations are discovered when the
-fibon package is configured. Benchmarks are searched for in the
-`benchmarks/Fibon/Benchmarks` directory and configuration files are
-searched for in the `config` directory. If a configuration file or
-benchmark is added, you will need to re-run `cabal configure` to
-make them available to the fibon-run tool.
-
-Configuration
----------------
-Fibon comes with a default configuration. The default configuration
-will run all benchmarks with the `Base` setting of `-O0` and a
-`Peak` setting of `-O2` on the `Ref` size. A configuration file can
-be used to specify more complicated configurations.
-
-You can get some example configuration by doing
-    $ git submodule update --init config
-
-This will checkout a repository of config files. Note that currently
-these files contain some user and machine-specific configurations,
-but should be a useful starting point.
-
-You can also selectively run benchmarks, groups, sizes, and tune
-settings as described below.
-
-Running
----------------
-Benchamarks are run with the `fibon-run` tool. Running `fibon-run`
-with no arguments will use the default config file. An alternate
-config file can be specified with the `-c` flag. Also, you can give
-a list of benchmarks or groups to run on the command line. Use
-`--help` to see a full list of options.
-
-Running the benchmarks will produce some logging to standard out and
-create four output files in the `log` directory.
-
-  1. `*.LOG` - the full log of the run
-  1. `*.SUMMARY` - the mean runtimes of each benchmark
-  1. `*.RESULTS` - the full results (passed to `fibon-analyse`)
-
-Analyzing Benchmark Results
-===================================================================
-Benchmarks can be analyzed by the `fibon-analyse` tool.
-
-    $ fibon-analyse log/000.default.RESULTS
-
-Adding New Benchmarks
-===================================================================
-TODO
-
-Benchmark Notes
-===================================================================
-Ghc610
-  ChameneosRedux
-    Does not work with -O0. Gets "thread blocked indefinitely"
-    exception
-
-  Mandelbrot
-    The Test size gives different result, but the Ref size is ok.
-    Think it is just some kind of floating point wibbles.
-
-[1]: http://hackage.haskell.org
-[2]: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#submodules
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,240 @@
+Fibon in a Flash
+===================================================================
+    $ git clone git://github.com/dmpots/fibon.git
+    $ cd fibon
+    $ git submodule update --init benchmarks
+    $ cabal configure && cabal build
+    $ ./dist/build/fibon-run/fibon-run
+
+Introduction
+===================================================================
+Fibon is a set of tools for running and analyzing benchmark programs in
+Haskell. Most importantly, it includes an optional set of new [benchmarks][2]
+including many programs taken from the [Hackage][1] open source repository.
+
+Fibon is a pure Haskell framework for running and analyzing benchmarks. Cabal
+is used for building the benchmarks, and the benchmark harness, configuration
+files, and benchmark descriptions are all written in Haskell. The benchmark
+descriptions and run configurations are all statically compiled into the
+benchmark runner to ensure that configuration errors are found at compile
+time.
+
+The Fibon tools are not tied to any compiler infrastructure and can build
+benchmarks using any compiler supported by cabal. However, there are some
+extra features available when using GHC to build the benchmarks:
+
+  * Support in config files for inplace GHC HEAD builds
+  * Support in `fibon-run` for collecting GC stats from GHC compiled programs
+  * Support in `fibon-analyse` for reading GC stats from Fibon result files
+
+Benchmarks
+------------------
+Fibon makes it easy to use either the Fibon benchmarks or your own
+set of benchmarks. Benchmarks are stored in the
+`benchmarks/Fibon/Benchmarks` directory. This directory is setup as
+a [git submodule][3] which means you can easily grab the standard
+suite or use a suite kept under your own source control.
+
+The default suite of benchmarks is stored in the
+[fibon-benchmarks][2] repository on github.
+
+Benchmark Groups
+------------------
+Benchmarks are named and organized into groups based on the filesystem
+organization. For example, a benchmark in the directory
+`benchmarks/Fibon/Benchmarks/Hackage/Agum` will have the name `Agum`
+an be in the benchmark group `Hackage`.
+
+Executables
+------------------
+The fibon package builds three tools:
+
+1. `fibon-run` - runs the benchmarks
+2. `fibon-analyze` - analyzes the results of a run
+3. `fibon-init` - utility used when adding new benchmarks
+
+Size and Tune
+------------------
+Fibon benchmarks can be run with two different input sizes: `Test` and `Ref`.
+The `Test` size is useful to make sure that a benchmark can run successfully,
+but will not give meaningful timings. The `Ref` size should be used when
+reporting results.
+
+Fibon benchmarks can be run under two different tune settings (e.g.
+compiler optimization settings). The `Base` and `Peak` settings can
+be configured anyway you want to make the desired comparison.
+
+Directory Structure
+--------------------
+Source directories
+
+    ./benchmarks -- benchmark code
+    ./config     -- config files
+    ./lib        -- common files used by several executables
+    ./tools      -- source code for executables
+
+Working directories
+
+    ./log        -- logging output from benchmark runs
+    ./run        -- working directory for benchmark runs
+
+Getting the Benchmarks
+===================================================================
+The benchmarks are kept in a separate repository as a git
+submodule. You can get the Fibon benchmarks by updating the
+submodule from within your Fibon working directory
+
+    $ git submodule update --init benchmarks
+
+This will checkout the benchmarks from the [fibon-benchmarks][2]
+repository and place them in your working copy.
+
+Running Benchmarks
+===================================================================
+The available benchmarks and configurations are discovered when the
+Fibon package is configured. Benchmarks are searched for in the
+`benchmarks/Fibon/Benchmarks` directory and configuration files are
+searched for in the `config` directory. If a configuration file or
+benchmark is added, you will need to re-run `cabal configure` to
+make them available to the fibon-run tool.
+
+Configuration
+---------------
+Fibon comes with a default configuration. The default configuration
+will run all benchmarks with the `Base` setting of `-O0` and a
+`Peak` setting of `-O2` on the `Ref` size. A configuration file can
+be used to specify more complicated configurations.
+
+You can get some example configuration by doing
+    $ git submodule update --init config
+
+This will checkout a repository of config files. Note that currently
+these files contain some user and machine-specific configurations,
+but should be a useful starting point.
+
+You can also command line options to selectively run benchmarks,
+groups, sizes, and tune settings as described below.
+
+Running
+---------------
+Benchmarks are run with the `fibon-run` tool. Running `fibon-run`
+with no arguments will use the default config file. An alternate
+config file can be specified with the `-c` flag. Also, you can give
+a list of benchmarks or groups to run on the command line. Use
+`--help` to see a full list of options.
+
+Running the benchmarks will produce some logging to standard out and
+create four output files in the `log` directory.
+
+1. `*.LOG` - the full log of the run
+2. `*.SUMMARY` - the mean runtimes of each benchmark
+3. `*.RESULTS`  - the full results in binary format (pass to `fibon-analyse`)
+4. `*.RESULTS.SHOW` - the full results in text format (pass to `fibon-analyse`)
+
+Analyzing Benchmark Results
+===================================================================
+Benchmarks can be analyzed by the `fibon-analyse` tool.
+
+    $ fibon-analyse log/000.default.RESULTS
+or
+
+    $ fibon-analyse log/000.default.RESULTS.SHOW
+
+The binary results (`.RESULT`) file is much faster to parse. It
+contains a serialization of a list of `FibonResult` structures. The
+`.SHOW` file contains a `FibonResult` on each line which can be
+parsed by using the `read` function.
+
+Adding New Benchmarks
+===================================================================
+
+New benchmarks are added by putting the appropriate files in the
+`benchmarks/Fibon/Benchmarks` directory. Each folder in this directory
+represents a benchmark group. The benchmarks and groups are found at
+configuration time (i.e. when running `cabal configure` for the fibon
+package). You can exclude a benchmark or a group by prefixing the name with
+and underscore (`_`).
+
+To add a new benchmark create a new folder in a benchmark group. If the
+benchmark program has been cabalized, you can typically just do a
+`cabal unpack` of the benchmark. The benchmark folder must contain:
+
+  1. A cabal file describing how to build the benchmark
+  2. A benchmark description for Fibon stored in `Fibon/Instance.hs`
+
+The `fibon-init` tool will read a cabal file from the current directory and generate the Fibon subfolder and a stub `Instance.hs` file.
+
+The `Fibon` subfolder of a benchmark contains all of the data that Fibon needs
+to build and execute the benchmark. The benchmark instance file describes any
+requried build flags, inputs, and outputs for the benchmark. It is a standard
+Haskell module that must export the `mkInstance` function. The `mkInstance`
+function takes a benchmark size and returns a `BenchmarkInstance` structure.
+An example instance file is show below.
+
+    module Fibon.Benchmarks.Hackage.Bzlib.Fibon.Instance(
+      mkInstance
+    )
+    where
+    import Fibon.BenchmarkInstance
+
+    sharedConfig = BenchmarkInstance {
+        flagConfig = FlagConfig {
+            configureFlags = []
+          , buildFlags     = []
+          , runFlags       = []
+          }
+        , stdinInput     = Nothing
+        , output         = []
+        , exeName        = "hsbzip"
+      }
+    flgCfg = flagConfig sharedConfig
+
+    mkInstance Test = sharedConfig {
+          flagConfig = flgCfg {
+              runFlags = ["bzlib.cabal.bz2"]
+          }
+          , output    = [(OutputFile "bzlib.cabal.bz2.roundtrip",
+                          Diff       "bzlib.cabal.bz2")]
+        }
+    mkInstance Ref  = sharedConfig {
+          flagConfig = flgCfg {
+              runFlags = ["mito.aa.bz2"]
+          }
+          , output   = [(OutputFile "mito.aa.bz2.roundtrip",
+                         Diff       "mito.aa.bz2")]
+        }
+
+The input and expected output data should also be stored in the `Fibon`
+subdirectory of the benchmark. When the benchmark is run, the contents of the
+input and output directories for the benchmark size will be copied to the
+working directory where the benchmark is run. There can also be an `all`
+directory which whose data will be copied for all input sizes. None of the
+data directories are required, but if they exist they must be organized like
+this:
+
+        data/all/input
+        data/all/output
+        data/ref/input
+        data/ref/output
+        data/test/input
+        data/test/output
+
+Benchmark Notes
+===================================================================
+Ghc612
+  The Repa and Dph groups will not work properly.
+
+Ghc610
+  The Repa and Dph groups will not work properly.
+  
+  ChameneosRedux
+    Does not work with -O0. Gets "thread blocked indefinitely"
+    exception
+
+  Mandelbrot
+    The Test size gives different result, but the Ref size is ok.
+    Think it is just some kind of floating point wibbles.
+
+[1]: http://hackage.haskell.org
+[2]: http://github.com/dmpots/fibon-benchmarks
+[3]: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#submodules
diff --git a/fibon.cabal b/fibon.cabal
--- a/fibon.cabal
+++ b/fibon.cabal
@@ -1,22 +1,34 @@
 -- The name of the package.
 Name:                fibon
-Version:             0.1.0
-Synopsis:            A reworking of the classic nofib benchmark suite
+Version:             0.2.0
+Synopsis:            Tools for running and analyzing Haskell benchmarks 
 Description:         
   Fibon is a set of tools for running and analyzing benchmark programs.
   The fibon package contains the tools for benchmarking, but not the
   benchmarks themselves. The package will build, but will not have any
-  benchmarks to run. A set of benchmarks can be found at
-
-  http://github.com/dmpots/fibon-benchmarks
-
-  Installing the cabal package will get you the following tools
-
-    * fibon - runs the benchmarks
-    * fibon-analyse - analyses the results of a benchmark run
-    * fibon-init - generate a benchmark description from a cabal file
+  benchmarks to run. A set of benchmarks can be found in the github repo
+  .
+  <http://github.com/dmpots/fibon-benchmarks>
+  .
+  Fibon is a pure Haskell framework for running and analyzing benchmarks. Cabal
+  is used for building the benchmarks, and the benchmark harness, configuration
+  files, and benchmark descriptions are all written in Haskell. The benchmark
+  descriptions and run configurations are all statically compiled into the
+  benchmark runner to ensure that configuration errors are found at compile
+  time.
+  .
+  The Fibon tools are not tied to any compiler infrastructure and can build
+  benchmarks using any compiler supported by cabal. However, there are some
+  extra features available when using GHC to build the benchmarks:
 
-  See http://github.com/dmpots/fibon/wiki for more details
+  * Support in config files for inplace GHC HEAD builds
+  
+  * Support in `fibon-run` for collecting GC stats from GHC compiled programs
+  
+  * Support in `fibon-analyse` for reading GC stats from Fibon result files
+    
+  .
+  For more details see the Fibon wiki: <http://github.com/dmpots/fibon/wiki>
 License:             BSD3
 License-file:        LICENSE
 Author:              David M Peixotto
@@ -28,7 +40,7 @@
 Build-type:          Custom
 Cabal-version:       >=1.8
 
-Extra-source-files: README
+Extra-source-files: README.md
                     FindBench.hs
                     FindConfig.hs
                     lib/Fibon/BenchmarkInstance.hs
@@ -37,8 +49,8 @@
                     lib/Fibon/InputSize.hs
                     lib/Fibon/Result.hs
                     lib/Fibon/Timeout.hs
-                    tools/fibon-analyse/Fibon/Analyse/AnalysisRoutines.hs
                     tools/fibon-analyse/Fibon/Analyse/Analysis.hs
+                    tools/fibon-analyse/Fibon/Analyse/AnalysisRoutines.hs
                     tools/fibon-analyse/Fibon/Analyse/CommandLine.hs
                     tools/fibon-analyse/Fibon/Analyse/ExtraStats/GhcStats.hs
                     tools/fibon-analyse/Fibon/Analyse/ExtraStats.hs
@@ -47,6 +59,7 @@
                     tools/fibon-analyse/Fibon/Analyse/Output.hs
                     tools/fibon-analyse/Fibon/Analyse/Parse.hs
                     tools/fibon-analyse/Fibon/Analyse/Result.hs
+                    tools/fibon-analyse/Fibon/Analyse/Statistics.hs
                     tools/fibon-analyse/Fibon/Analyse/Tables.hs
                     tools/fibon-init/Main.hs
                     tools/fibon-run/Fibon/Run/Actions.hs
@@ -68,7 +81,7 @@
 source-repository this
   type:     git
   location: git://github.com/dmpots/fibon.git
-  tag:      v0.1.0
+  tag:      v0.2.0
 
 Flag analyse
   description: Build the fibon-analyse program
@@ -91,9 +104,12 @@
                 , process     == 1.0.*
                 , time        == 1.1.*
                 , old-locale  == 1.0.*
+                , old-time    == 1.0.*
                 , statistics  == 0.6.*
                 , vector      == 0.6.*
---  other-modules:  Fibon.Benchmarks
+                , bytestring  == 0.9.*
+                , cereal      == 0.3.*
+                , syb         == 0.1.*
 
 Executable fibon-init
   main-is:        Main.hs
@@ -102,7 +118,7 @@
   build-depends:  base >= 4 && < 5
                 , filepath    == 1.1.*
                 , directory   == 1.0.*
-                , Cabal == 1.8.*
+                , Cabal       == 1.8.*
 
 Executable fibon-analyse
   if (flag(analyse))
@@ -118,10 +134,14 @@
                     , mtl        == 1.1.*
                     , filepath   == 1.1.*
                     , bytestring == 0.9.*
-                    , text       == 0.8.*
                     , tabular    == 0.2.*
                     , vector     == 0.6.*
                     , statistics == 0.6.*
+                    , regex-compat == 0.93.*
+                    , attoparsec == 0.8.*
+                    , bytestring-lexing == 0.2.*
+                    , cereal     == 0.3.*
+                    , syb        == 0.1.*
   extensions: CPP
 
 
diff --git a/lib/Fibon/ConfigMonad.hs b/lib/Fibon/ConfigMonad.hs
--- a/lib/Fibon/ConfigMonad.hs
+++ b/lib/Fibon/ConfigMonad.hs
@@ -14,6 +14,7 @@
   , noExtraStats
   , useGhcDir
   , useGhcInPlaceDir
+  , getEnv
 )
 where
 
@@ -38,6 +39,7 @@
     flags          :: a
   , limit          :: Timeout
   , extraStatsFile :: Maybe FilePath
+  , environment    :: [(String, String)]
   }
 type ConfigMap   = Map.Map FlagParameter [String]
 type ConfigMonad = GenConfigMonad ()
@@ -47,25 +49,25 @@
 done = CM (return ())
 
 replace :: FlagParameter -> String -> ConfigMonad
-replace p f = do
-  CM $ modify $ (\c -> c {flags = Map.insert p [f] (flags c)})
+replace p f = CM $
+  modify $ (\c -> c {flags = Map.insert p [f] (flags c)})
 
 append :: FlagParameter -> String -> ConfigMonad
-append p f = do
-  CM $ modify $ (\c -> c {flags = Map.insertWith (flip (++)) p as (flags c)})
+append p f = CM $
+  modify $ (\c -> c {flags = Map.insertWith (flip (++)) p as (flags c)})
   where as = words f
 
 setTimeout :: Timeout -> ConfigMonad
-setTimeout t = do
-  CM $ modify $ (\c -> c {limit = t})
+setTimeout t = CM $
+  modify $ (\c -> c {limit = t})
 
 collectExtraStatsFrom :: FilePath -> ConfigMonad
-collectExtraStatsFrom f = do
-  CM $ modify $ (\c -> c {extraStatsFile = Just f})
+collectExtraStatsFrom f = CM $
+  modify $ (\c -> c {extraStatsFile = Just f})
 
 noExtraStats :: ConfigMonad
-noExtraStats = do
-  CM $ modify $ (\c -> c {extraStatsFile = Nothing})
+noExtraStats = CM $
+  modify $ (\c -> c {extraStatsFile = Nothing})
 
 useGhcDir :: FilePath -> ConfigMonad
 useGhcDir dir = do
@@ -77,13 +79,19 @@
   append ConfigureFlags $ "--with-ghc="++(dir </> "ghc-stage2")
   append ConfigureFlags $ "--with-ghc-pkg="++(dir </> "ghc-pkg")
 
-runWithInitialFlags :: FlagConfig -> ConfigMonad -> Configuration
-runWithInitialFlags fc cm = toConfig finalState
+getEnv :: String -> GenConfigMonad (Maybe String)
+getEnv s = CM $ do
+  e <- gets environment
+  return (lookup s e)
+
+runWithInitialFlags :: FlagConfig -> [(String, String)] -> ConfigMonad -> Configuration
+runWithInitialFlags fc progEnv cm = toConfig finalState
   where
   startState = ConfigState {
       flags          = fromFlagConfig fc
     , limit          = Infinity
     , extraStatsFile = Nothing
+    , environment    = progEnv
     }
   finalState = execState (configState cm) startState
 
diff --git a/lib/Fibon/Result.hs b/lib/Fibon/Result.hs
--- a/lib/Fibon/Result.hs
+++ b/lib/Fibon/Result.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveDataTypeable #-}
 module Fibon.Result (
     FibonResult(..)
   , RunData(..)
@@ -7,35 +8,61 @@
   , ExtraStats
 )
 where
+import Data.ByteString(ByteString)
+import Data.Serialize
+import Data.Generics
 
 data FibonResult = FibonResult {
       benchName   :: String
     , buildData   :: BuildData
     , runData     :: RunData
-  } deriving(Read, Show)
+  } deriving(Read, Show, Data, Typeable)
 
 data BuildData = BuildData {
       buildTime :: Double  -- ^ Time to build the program
     , buildSize :: String  -- ^ Size of the program
   }
-  deriving(Read, Show)
+  deriving(Read, Show, Data, Typeable)
 
 data RunData = RunData {
     summary :: RunSummary
   , details :: [RunDetail]
-  } deriving(Read, Show)
+  } deriving(Read, Show, Data, Typeable)
 
 data RunSummary = RunSummary {
       meanTime     :: Double
     , stdDevTime   :: Double
     , statsSummary :: ExtraStats
   }
-  deriving (Read, Show)
+  deriving (Read, Show, Data, Typeable)
 
 data RunDetail = RunDetail {runTime :: Double, runStats :: ExtraStats}
-  deriving (Read, Show)
+  deriving (Read, Show, Data, Typeable)
 
 --type ExtraStats = [(String, String)]
-type ExtraStats = String
+type ExtraStats = ByteString
 
+
+--
+-- Binary Instances
+--
+instance Serialize Fibon.Result.FibonResult where
+  put (FibonResult a b c) = put a >> put b >> put c
+  get = get >>= \a -> get >>= \b -> get >>= \c -> return (FibonResult a b c)
+
+instance Serialize Fibon.Result.BuildData where
+  put (BuildData a b) = put a >> put b
+  get = get >>= \a -> get >>= \b -> return (BuildData a b)
+
+instance Serialize Fibon.Result.RunData where
+  put (RunData a b) = put a >> put b
+  get = get >>= \a -> get >>= \b -> return (RunData a b)
+
+instance Serialize Fibon.Result.RunDetail where
+  put (RunDetail a b) = put a >> put b
+  get = get >>= \a -> get >>= \b -> return (RunDetail a b)
+
+instance Serialize Fibon.Result.RunSummary where
+  put (RunSummary a b c) = put a >> put b >> put c
+  get = get >>= \a -> get >>= \b -> get >>= \c -> return (RunSummary a b c)
 
diff --git a/tools/fibon-analyse/Fibon/Analyse/Analysis.hs b/tools/fibon-analyse/Fibon/Analyse/Analysis.hs
--- a/tools/fibon-analyse/Fibon/Analyse/Analysis.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/Analysis.hs
@@ -15,17 +15,20 @@
 import Fibon.Analyse.Parse
 import Fibon.Analyse.Result
 import Fibon.Analyse.Metrics
+import Fibon.Analyse.Statistics
 import Fibon.Analyse.Tables
-import Statistics.Sample
 import qualified Data.Vector.Unboxed as V
 
 runAnalysis :: Analysis a -> FilePath -> IO (Maybe [ResultColumn a])
 runAnalysis analysis file = do
-  fibonResults <- parseFibonResults file
+  fibonResults <- parse file
   case fibonResults of
     Nothing -> return Nothing
     Just rs -> do x <- createResultColumns analysis rs
                   return (Just x)
+  where
+    parse f | ".SHOW" `isSuffixOf` f = parseShowFibonResults   f
+            | otherwise              = parseBinaryFibonResults f
 
 createResultColumns :: Analysis a
                     -> M.Map ResultLabel [FibonResult] 
@@ -208,18 +211,3 @@
   return $ Summary how (Norm (makeNorm (computeSummary how vec)))
   where
     vec = V.fromList (map normPerfToDouble normPerfs)
-
-computeSummary :: Summary -> Sample -> Estimate Double
-computeSummary summaryType vec =
-  Estimate {
-      ePoint  = sumF summaryType vec
-    , eStddev = stdDev vec -- TODO: this is wrong stddev for geoMean
-    , eSize   = V.length vec
-    , eCI     = Nothing
-  }
-  where
-  sumF ArithMean = mean
-  sumF GeoMean   = geometricMean
-  sumF Max       = V.maximum
-  sumF Min       = V.minimum
-
diff --git a/tools/fibon-analyse/Fibon/Analyse/AnalysisRoutines.hs b/tools/fibon-analyse/Fibon/Analyse/AnalysisRoutines.hs
--- a/tools/fibon-analyse/Fibon/Analyse/AnalysisRoutines.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/AnalysisRoutines.hs
@@ -5,15 +5,17 @@
 )
 where
 
+import Data.ByteString(ByteString)
 import Fibon.Result
-import Fibon.Analyse.Result
-import Fibon.Analyse.Metrics
 import Fibon.Analyse.ExtraStats
+import Fibon.Analyse.Metrics
+import Fibon.Analyse.Parse
+import Fibon.Analyse.Result
 
 data Analysis a = Analysis {
-      fibonAnalysis :: (FibonResult -> IO FibonStats)-- ^ RunData analyser
-    , extraParser   :: (String  -> Maybe a)          -- ^ extraStats parser
-    , extraAnalysis :: ([a]     -> IO    a)          -- ^ extraStats analyser
+      fibonAnalysis :: (FibonResult  -> IO FibonStats)-- ^ RunData analyser
+    , extraParser   :: (ByteString -> Maybe a)        -- ^ extraStats parser
+    , extraAnalysis :: ([a]     -> IO    a)           -- ^ extraStats analyser
   }
 
 noAnalysis :: Analysis a
@@ -25,17 +27,19 @@
   where 
     getStats fr = FibonStats {
           compileTime = Single $ ExecTime ((buildTime . buildData) fr)
-        , binarySize  = Single $ MemSize 0 
+        , binarySize  = Single $ getSize (sizeData fr)
         , wallTime    = Single $ ExecTime ((meanTime . summary . runData) fr)
       }
+    getSize s = maybe (MemSize 0) MemSize (parseBinarySize s)
+    sizeData  = buildSize . buildData
 
 ghcStatsAnalysis :: Analysis GhcStats
 ghcStatsAnalysis = noAnalysis {
-      extraParser = parseGhcStats
+      extraParser   = parseGhcStats
+    , extraAnalysis = return . ghcStatsSummary
   }
-
+--TODO: make extraAnalysis for GhcStats acutally do some analysis
 --makeAnalysis :: Analysis a -> (String -> Maybe b) -> Analysis b
-
 
 
 
diff --git a/tools/fibon-analyse/Fibon/Analyse/ExtraStats.hs b/tools/fibon-analyse/Fibon/Analyse/ExtraStats.hs
--- a/tools/fibon-analyse/Fibon/Analyse/ExtraStats.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/ExtraStats.hs
@@ -1,10 +1,14 @@
 module Fibon.Analyse.ExtraStats(
     GhcStats.GhcStats(..)
   , parseGhcStats
+  , ghcStatsSummary
 )
 where
+import Data.ByteString(ByteString)
 import Fibon.Analyse.ExtraStats.GhcStats as GhcStats
 
-parseGhcStats :: String -> Maybe GhcStats
+parseGhcStats :: ByteString -> Maybe GhcStats
 parseGhcStats = GhcStats.parseMachineReadableStats
 
+ghcStatsSummary :: [GhcStats] -> GhcStats
+ghcStatsSummary = GhcStats.summarizeGhcStats
diff --git a/tools/fibon-analyse/Fibon/Analyse/ExtraStats/GhcStats.hs b/tools/fibon-analyse/Fibon/Analyse/ExtraStats/GhcStats.hs
--- a/tools/fibon-analyse/Fibon/Analyse/ExtraStats/GhcStats.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/ExtraStats/GhcStats.hs
@@ -1,10 +1,21 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
 module Fibon.Analyse.ExtraStats.GhcStats(
     GhcStats(..)
   , parseMachineReadableStats
+  , summarizeGhcStats
 )
 where
 
+import Control.Monad
+import Data.Attoparsec(maybeResult)
+import Data.Attoparsec.Char8
+import Data.ByteString(ByteString)
+import qualified Data.ByteString.Char8 as BC
+import Data.ByteString.Lex.Double
+import qualified Data.Vector.Unboxed as V
 import Fibon.Analyse.Metrics
+import Fibon.Analyse.Statistics as Statistics
 
 data GhcStats = GhcStats {
       bytesAllocated          :: Measurement MemSize
@@ -21,14 +32,122 @@
     , gcWallSeconds           :: Measurement ExecTime
 
     -- derived metrics
-    , ghcCpuTime                 :: Measurement ExecTime
-    , ghcWallTime                :: Measurement ExecTime
+    , ghcCpuTime              :: Measurement ExecTime
+    , ghcWallTime             :: Measurement ExecTime
   }
   deriving (Read, Show)
 
+parseMachineReadableStats :: ByteString -> Maybe GhcStats
+parseMachineReadableStats s = do
+  stats <- toAssocList s
+  let find = flip lookup stats
+  bytesA <- find "bytes allocated" >>= readMem
+  numG   <- find "num_GCs" >>= readMem
+  avgB   <- find "average_bytes_used" >>= readMem
+  maxB   <- find "max_bytes_used" >>= readMem
+  numS   <- find "num_byte_usage_samples" >>= readMem
+  peakA  <- find "peak_megabytes_allocated" >>= readMem
+  initC  <- find "init_cpu_seconds" >>= readTime
+  initW  <- find "init_wall_seconds" >>= readTime
+  mutC   <- find "mutator_cpu_seconds" >>= readTime
+  mutW   <- find "mutator_wall_seconds" >>= readTime
+  gcC    <- find "GC_cpu_seconds" >>= readTime
+  gcW    <- find "GC_wall_seconds" >>= readTime
+  ghcC   <- initC `addM` mutC >>= addM gcC
+  ghcW   <- initW `addM` mutW >>= addM gcW
+  return GhcStats {
+      bytesAllocated          = bytesA
+    , numGCs                  = numG
+    , averageBytesUsed        = avgB
+    , maxBytesUsed            = maxB
+    , numByteUsageSamples     = numS
+    , peakMegabytesAllocated  = peakA
+    , initCPUSeconds          = initC
+    , initWallSeconds         = initW
+    , mutatorCPUSeconds       = mutC
+    , mutatorWallSeconds      = mutW
+    , gcCPUSeconds            = gcC
+    , gcWallSeconds           = gcW
+    , ghcCpuTime              = ghcC
+    , ghcWallTime             = ghcW
+  }
+  where
+    addM :: Num a => Measurement a -> Measurement a -> Maybe (Measurement a)
+    addM (Single a) (Single b) = Just $ Single (a+b)
+    addM _ _ = Nothing
 
+--
+-- Parsing Routines
+--
+toAssocList :: ByteString -> Maybe [(ByteString, ByteString)]
+toAssocList = maybeResult . parse parseList . BC.unlines . drop 1 . BC.lines
 
-parseMachineReadableStats :: String -> Maybe GhcStats
-parseMachineReadableStats _ = Nothing
+readMem :: ByteString -> Maybe (Measurement MemSize)
+readMem s = (Single . MemSize . fromIntegral . fst) `liftM` (BC.readInteger s)
 
+readTime :: ByteString -> Maybe (Measurement ExecTime)
+readTime s = (Single . ExecTime . fst) `liftM` (readDouble s)
 
+parseList :: Parser [(ByteString, ByteString)]
+parseList = do
+  skipSpace
+  char '['
+  tups <- parseTuple `sepBy` (skipSpace >> char ',')
+  skipSpace
+  char ']'
+  return tups
+
+parseTuple :: Parser (ByteString, ByteString)
+parseTuple = do
+  skipSpace
+  char '(' >> skipSpace
+  s1 <- parseString
+  char ',' >> skipSpace
+  s2 <- parseString
+  skipSpace
+  char ')'
+  return (s1, s2)
+
+parseString :: Parser ByteString
+parseString = do
+  char '"'
+  s <- takeTill ('"'==)
+  char '"'
+  return s
+
+--
+-- Analysis Functions
+--
+summarizeGhcStats :: [GhcStats] -> GhcStats
+summarizeGhcStats stats =
+  GhcStats {
+      bytesAllocated          = sumMem  bytesAllocated
+    , numGCs                  = sumMem  numGCs
+    , averageBytesUsed        = sumMem  averageBytesUsed
+    , maxBytesUsed            = sumMem  maxBytesUsed
+    , numByteUsageSamples     = sumMem  numByteUsageSamples
+    , peakMegabytesAllocated  = sumMem  peakMegabytesAllocated
+    , initCPUSeconds          = sumTime initCPUSeconds
+    , initWallSeconds         = sumTime initWallSeconds
+    , mutatorCPUSeconds       = sumTime mutatorCPUSeconds
+    , mutatorWallSeconds      = sumTime mutatorWallSeconds
+    , gcCPUSeconds            = sumTime gcCPUSeconds
+    , gcWallSeconds           = sumTime gcWallSeconds
+    , ghcCpuTime              = sumTime ghcCpuTime
+    , ghcWallTime             = sumTime ghcWallTime
+  }
+  where
+    sumMem  f = Interval $ summarize stats fromIntegral round f
+    sumTime f = Interval $ summarize stats fromExecTime ExecTime f
+
+summarize :: [GhcStats]                   -- ^ Stats to summarize
+          -> (a -> Double)                -- ^ Conversion to double
+          -> (Double -> a)                -- ^ Conversion back from double
+          -> (GhcStats -> Measurement a)  -- ^ Field accessor
+          -> Estimate a
+summarize stats toDouble toMeasurement f =
+  fmap toMeasurement $ Statistics.computeSummary ArithMean rawNums
+  where
+    rawNums = V.fromList $ map (getD . f) stats
+    getD (Single m)   = toDouble m
+    getD (Interval e) = (toDouble . ePoint) e
diff --git a/tools/fibon-analyse/Fibon/Analyse/Main.hs b/tools/fibon-analyse/Fibon/Analyse/Main.hs
--- a/tools/fibon-analyse/Fibon/Analyse/Main.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/Main.hs
@@ -11,14 +11,14 @@
 main :: IO ()
 main = do
   (opts, files) <- getCommandLine
-  mbResults <- mapM (\f -> runAnalysis noAnalysis f) files
+  mbResults <- mapM (runAnalysis ghcStatsAnalysis) files
   case concat `fmap` sequence mbResults of
     Nothing -> putStrLn "Error Parsing Results"
     Just rs -> do
       let fmt  = optOutputFormat opts
       let norm = getNormFun opts
-      putStrLn $ renderSummaryTable rs norm fmt basicTable
-      putStrLn $ renderTables       rs norm fmt basicTable
+      putStrLn $ renderSummaryTable rs norm fmt ghcStatsSummaryTable
+      putStrLn $ renderTables       rs norm fmt ghcStatsSummaryTable
 
 
 getCommandLine :: IO (Opt, [FilePath])
diff --git a/tools/fibon-analyse/Fibon/Analyse/Metrics.hs b/tools/fibon-analyse/Fibon/Analyse/Metrics.hs
--- a/tools/fibon-analyse/Fibon/Analyse/Metrics.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/Metrics.hs
@@ -11,7 +11,6 @@
   , RawPerf(..)
   , NormPerf(..)
   , BasicPerf(..)
-  , Summary(..)
   , mkPointEstimate
   , rawPerfToDouble
   , normPerfToDouble
@@ -19,40 +18,13 @@
 where
 
 import Data.Word
+import Fibon.Analyse.Statistics
 import Text.Printf
 
 newtype MemSize    = MemSize  {fromMemSize  :: Word64}
-  deriving(Eq, Num, Read, Show)
+  deriving(Eq, Read, Show, Num, Real, Enum, Ord, Integral)
 newtype ExecTime   = ExecTime {fromExecTime :: Double}
-  deriving(Eq, Num, Read, Show)
-
-data Estimate a = Estimate {
-      ePoint  :: !a
-    , eStddev :: !a
-    , eSize   :: !Int
-    , eCI     :: Maybe (ConfidenceInterval a)
-  }
-  deriving (Read, Show)
-
-data ConfidenceInterval a = ConfidenceInterval {
-      eLowerBound       :: !a
-    , eUpperBound       :: !a
-    , eConfidenceLevel  :: !Double
-}
-  deriving (Read, Show)
-
-instance Functor Estimate where
-  fmap f e = e {
-      ePoint  = f (ePoint e)
-    , eStddev = f (eStddev e)
-    , eCI     = maybe Nothing (Just . fmap f) (eCI e)
-  }
-
-instance Functor ConfidenceInterval where
-  fmap f c = c {
-      eLowerBound = f (eLowerBound c)
-    , eUpperBound = f (eUpperBound c)
-  }
+  deriving(Eq, Read, Show, Num, Real, Enum, Ord)
 
 data Measurement a = 
     Single   a
@@ -60,9 +32,9 @@
   deriving (Read, Show)
 
 mkPointEstimate :: (Num b) => (b -> a) -> a -> Estimate a
-mkPointEstimate mkA a = Estimate {
+mkPointEstimate toA a = Estimate {
       ePoint  = a
-    , eStddev = mkA 0
+    , eStddev = toA 0
     , eSize   = 1
     , eCI     = Nothing
   }
@@ -102,13 +74,6 @@
 data NormPerf =
     Percent (Estimate Double) -- ^ (ref  / base) * 100
   | Ratio   (Estimate Double) -- ^ (base / ref)
-  deriving(Read, Show)
-
-data Summary =
-    Min
-  | GeoMean
-  | ArithMean
-  | Max
   deriving(Read, Show)
 
 pprPerfData :: Bool -> PerfData -> String
diff --git a/tools/fibon-analyse/Fibon/Analyse/Parse.hs b/tools/fibon-analyse/Fibon/Analyse/Parse.hs
--- a/tools/fibon-analyse/Fibon/Analyse/Parse.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/Parse.hs
@@ -1,43 +1,81 @@
 module Fibon.Analyse.Parse(
     GhcStats(..)
-  , parseFibonResults
+  , parseShowFibonResults
+  , parseBinaryFibonResults
+  , parseBinarySize
+  , ParseResult
 )
 where
 
+import Data.Char
+import qualified Data.ByteString as B
 import qualified Data.Map        as M
-import qualified Data.Text       as T
-import qualified Data.Text.IO    as T
+import Data.Serialize
+import Data.Word
 import Fibon.Result
 import Fibon.Analyse.ExtraStats
 import Fibon.Analyse.Result
 import System.FilePath
+import Text.Regex
 
+type ParseResult = M.Map ResultLabel [FibonResult]
 
-parseFibonResults :: FilePath  -- ^ input file
-                  -> IO (Maybe (M.Map ResultLabel [FibonResult])) -- ^ Result
-parseFibonResults file = do
-  input <- T.readFile file
+parseShowFibonResults :: FilePath -> IO (Maybe ParseResult)
+parseShowFibonResults file = do
+  input <- readFile file
   case runParser input of
     Nothing -> return Nothing
     Just [] -> return Nothing
-    Just rs -> return (Just $ M.mapKeys addFileSource (groupResults rs))
+    Just rs -> return (Just $ convertToMap file rs)
   where
-    baseName        = takeBaseName file
-    addFileSource s = baseName ++ s
-
-    runParser :: T.Text -> Maybe [FibonResult]
-    runParser text = sequence (map parseLine (T.lines text))
+    runParser :: String -> Maybe [FibonResult]
+    runParser text = sequence (map parseLine (lines text))
 
-    parseLine :: T.Text -> Maybe FibonResult
+    parseLine :: String -> Maybe FibonResult
     parseLine line = 
-      case reads (T.unpack line) of
+      case reads line of
         [(r, _)] -> Just r
         _        -> Nothing
 
-groupResults :: [FibonResult] -> M.Map ResultLabel [FibonResult]
+parseBinaryFibonResults :: FilePath -> IO (Maybe ParseResult)
+parseBinaryFibonResults file = do
+  input <- B.readFile file
+  case decode input of
+    Left   _ -> return Nothing
+    Right [] -> return Nothing
+    Right rs -> return (Just $ convertToMap file rs)
+
+convertToMap :: FilePath -> [FibonResult] -> ParseResult
+convertToMap file rs = M.mapKeys addFileSource (groupResults rs)
+  where
+    addFileSource s = baseName ++ s
+    baseName        = takeWhile (/= '.')  (takeBaseName file)
+
+groupResults :: [FibonResult] -> ParseResult
 groupResults = foldr grouper M.empty
   where
   grouper   r = M.insertWith (++)  (benchType r) [r]
   benchType r = dropWhile (/= '-') (benchName r)
 
+
+-- | Parses the output of the @size@ command.
+--   The output is of the form:
+--
+--    text\t   data\t    bss\t    dec\t    hex
+--    817842\t  49536\t  48136\t 915514\t  df83a
+--
+parseBinarySize :: String -> Maybe Word64
+parseBinarySize s =
+  case lines s of
+    [header, sizes] ->
+      let keys   = splitRegex sp (dropWhile isSpace header)
+          values = splitRegex sp (dropWhile isSpace sizes)
+      in
+          lookup "dec" (zip keys values) >>= mbParse
+    _ -> Nothing
+    where
+    mbParse w = case reads w of [(size,_)] -> Just size; _ -> Nothing
+
+sp :: Regex
+sp = mkRegex "[ \t]+"
 
diff --git a/tools/fibon-analyse/Fibon/Analyse/Statistics.hs b/tools/fibon-analyse/Fibon/Analyse/Statistics.hs
new file mode 100644
--- /dev/null
+++ b/tools/fibon-analyse/Fibon/Analyse/Statistics.hs
@@ -0,0 +1,60 @@
+module Fibon.Analyse.Statistics(
+    computeSummary
+  , Summary(..)
+  , Estimate(..)
+  , ConfidenceInterval(..)
+)
+where
+
+import Statistics.Sample
+import qualified Data.Vector.Unboxed as V
+
+data Summary =
+    Min
+  | GeoMean
+  | ArithMean
+  | Max
+  deriving(Read, Show)
+
+data Estimate a = Estimate {
+      ePoint  :: !a
+    , eStddev :: !a
+    , eSize   :: !Int
+    , eCI     :: Maybe (ConfidenceInterval a)
+  }
+  deriving (Read, Show)
+
+data ConfidenceInterval a = ConfidenceInterval {
+      eLowerBound       :: !a
+    , eUpperBound       :: !a
+    , eConfidenceLevel  :: !Double
+}
+  deriving (Read, Show)
+
+instance Functor Estimate where
+  fmap f e = e {
+      ePoint  = f (ePoint e)
+    , eStddev = f (eStddev e)
+    , eCI     = maybe Nothing (Just . fmap f) (eCI e)
+  }
+
+instance Functor ConfidenceInterval where
+  fmap f c = c {
+      eLowerBound = f (eLowerBound c)
+    , eUpperBound = f (eUpperBound c)
+  }
+
+computeSummary :: Summary -> Sample -> Estimate Double
+computeSummary summaryType vec =
+  Estimate {
+      ePoint  = sumF summaryType vec
+    , eStddev = stdDev vec -- TODO: this is wrong stddev for geoMean
+    , eSize   = V.length vec
+    , eCI     = Nothing
+  }
+  where
+  sumF ArithMean = mean
+  sumF GeoMean   = geometricMean
+  sumF Max       = V.maximum
+  sumF Min       = V.minimum
+
diff --git a/tools/fibon-analyse/Fibon/Analyse/Tables.hs b/tools/fibon-analyse/Fibon/Analyse/Tables.hs
--- a/tools/fibon-analyse/Fibon/Analyse/Tables.hs
+++ b/tools/fibon-analyse/Fibon/Analyse/Tables.hs
@@ -21,6 +21,7 @@
 ghcStatsSummaryTable :: TableSpec GhcStats
 ghcStatsSummaryTable = [
       ColSpec "Size"       (onFibonStats binarySize)
+    , ColSpec "Compile"    (onFibonStats compileTime)
     , ColSpec "Allocs"     (onExtraStats bytesAllocated)
     , ColSpec "Runtime"    (onExtraStats ghcCpuTime)
     , ColSpec "Elapsed"    (onExtraStats ghcWallTime)
diff --git a/tools/fibon-run/Fibon/Run/BenchmarkBundle.hs b/tools/fibon-run/Fibon/Run/BenchmarkBundle.hs
--- a/tools/fibon-run/Fibon/Run/BenchmarkBundle.hs
+++ b/tools/fibon-run/Fibon/Run/BenchmarkBundle.hs
@@ -53,8 +53,9 @@
          -> String   -- ^ unique id
          -> InputSize
          -> TuneSetting
+         -> [(String, String)] -- ^ Environment variables
          -> BenchmarkBundle
-mkBundle rc bm wd bmsDir uniq size tune =
+mkBundle rc bm wd bmsDir uniq size tune progEnv =
   BenchmarkBundle {
       benchmark     = bm
     , workDir       = wd
@@ -69,7 +70,7 @@
     , extraStats    = (extraStatsFile configuration)
   }
   where
-    configuration = mkConfig rc bm size tune
+    configuration = mkConfig rc bm size tune progEnv
 
 bundleName :: BenchmarkBundle -> String
 bundleName bb = concat $ intersperse "-"
diff --git a/tools/fibon-run/Fibon/Run/BenchmarkRunner.hs b/tools/fibon-run/Fibon/Run/BenchmarkRunner.hs
--- a/tools/fibon-run/Fibon/Run/BenchmarkRunner.hs
+++ b/tools/fibon-run/Fibon/Run/BenchmarkRunner.hs
@@ -8,8 +8,9 @@
 import Control.Concurrent
 import Control.Monad
 import Control.Exception
-import Data.Time.Clock
+import qualified Data.ByteString as B
 import Data.Maybe
+import Data.Time.Clock
 import qualified Data.Vector.Unboxed as Vector
 import Fibon.BenchmarkInstance
 import Fibon.Result
@@ -116,16 +117,14 @@
       logReadE :: IOException -> IO ExtraStats
       logReadE e =
         Log.warn ("Error reading stats file: "++statsFile++"\n  "++show e)
-        >> return []
-      --logParseE =
-      --  Log.warn ("Error parsing stats file: "++statsFile) >> return []
+        >> return B.empty
   case mbStatsFile of
-    Nothing -> return []
+    Nothing -> return B.empty
     Just f  -> do
       handle logReadE $
         bracket (openFile ((pathToExeRunDir bb) </> f) ReadMode)
                 (hClose)
-                (\h -> hGetContents h >>= \s -> length s `seq` return s)
+                (\h -> B.hGetContents h >>= \s -> B.length s `seq` return s)
                     --stats <- hGetContents h
                     -- drop header line in machine readable stats
                     --let body = (unlines . drop 1 . lines) stats
@@ -160,7 +159,7 @@
   }
   where
     times = (Vector.fromList $ map runTime ds)
-    stats = concatMap runStats ds
+    stats = case ds of (x:_) -> runStats x; _ -> B.empty
 
 type TimeoutLength = Int
 runBenchmarkWithTimeout :: TimeoutLength -> BenchmarkBundle -> RunStepResult
diff --git a/tools/fibon-run/Fibon/Run/Config.hs b/tools/fibon-run/Fibon/Run/Config.hs
--- a/tools/fibon-run/Fibon/Run/Config.hs
+++ b/tools/fibon-run/Fibon/Run/Config.hs
@@ -6,6 +6,7 @@
   , Fibon.ConfigMonad.noExtraStats
   , Fibon.ConfigMonad.useGhcDir
   , Fibon.ConfigMonad.useGhcInPlaceDir
+  , Fibon.ConfigMonad.getEnv
   , Fibon.Timeout.Timeout(..)
   , Fibon.ConfigMonad.FlagParameter(..)
   , Fibon.ConfigMonad.Configuration
@@ -67,8 +68,9 @@
                 -> FibonBenchmark
                 -> InputSize
                 -> TuneSetting
+                -> [(String, String)]
                 -> Configuration
-mkConfig rc bm size tune = runWithInitialFlags benchFlags configM
+mkConfig rc bm size tune env = runWithInitialFlags benchFlags env configM
   where
   configM = mapM_ (uncurry builder) [
         (ConfigTuneDefault, ConfigBenchDefault)
diff --git a/tools/fibon-run/Fibon/Run/Log.hs b/tools/fibon-run/Fibon/Run/Log.hs
--- a/tools/fibon-run/Fibon/Run/Log.hs
+++ b/tools/fibon-run/Fibon/Run/Log.hs
@@ -28,12 +28,13 @@
 summaryLog :: String
 summaryLog = "Fibon.Summary"
 
-setupLogger :: FilePath -> FilePath -> String -> IO (FilePath, FilePath, FilePath)
+setupLogger :: FilePath -> FilePath -> String -> IO (FilePath, FilePath, FilePath, FilePath)
 setupLogger logDir outDir runId = do
   let logFileName = printf "%s.LOG" runId
       logPath     = logDir </> logFileName
-      resultPath  = outDir </> (printf "%s.RESULTS" runId)
+      resultPath  = outDir </> (printf "%s.RESULTS.SHOW" runId)
       summaryPath = outDir </> (printf "%s.SUMMARY" runId)
+      binaryPath  = outDir </> (printf "%s.RESULTS"  runId)
   ldExists <- doesDirectoryExist logDir
   unless ldExists (createDirectory logDir)
   h  <- openFile logPath WriteMode
@@ -44,7 +45,7 @@
   updateGlobalLogger rootLoggerName (setLevel DEBUG . setHandlers [ch,fh])
   updateGlobalLogger resultLog      (setLevel DEBUG . setHandlers [rh])
   updateGlobalLogger summaryLog     (setLevel DEBUG . setHandlers [sh])
-  return (logPath, resultPath, summaryPath)
+  return (logPath, resultPath, summaryPath, binaryPath)
 
 debug, info, notice, warn, error :: String -> IO ()
 debug  = debugM fibonLog
diff --git a/tools/fibon-run/Fibon/Run/Main.hs b/tools/fibon-run/Fibon/Run/Main.hs
--- a/tools/fibon-run/Fibon/Run/Main.hs
+++ b/tools/fibon-run/Fibon/Run/Main.hs
@@ -4,8 +4,11 @@
 where 
 import Control.Monad
 import Control.Exception
+import qualified Data.ByteString as B
 import Data.Char
 import Data.List
+import Data.Maybe
+import Data.Serialize
 import Data.Time.Clock
 import Data.Time.Format
 import Data.Time.LocalTime
@@ -22,6 +25,7 @@
 import System.Environment
 import System.FilePath
 import System.Locale
+import System.Time
 import Text.Printf
 
 
@@ -36,18 +40,23 @@
       logPath    = currentDir </> "log"
       action     = optAction opts
   uniq       <- chooseUniqueName workingDir (configId runConfig)
-  (logFile, outFile, summaryFile) <- Log.setupLogger logPath logPath uniq
+  (logFile, showFile, summaryFile, binFile) <- Log.setupLogger logPath logPath uniq
   startTime <- timeStamp
-  Log.notice ("Starting Run at   " ++ startTime)
-  Log.notice ("Logging output  to " ++ logFile)
-  Log.notice ("Logging result  to " ++ outFile)
-  Log.notice ("Logging summary to " ++ summaryFile)
-  mapM_ (runAndReport action) (makeBundles runConfig workingDir benchRoot uniq)
+  progEnv <- getEnvironment
+  Log.notice ("Starting Run at   " ++ prettyTimeStamp startTime)
+  Log.notice ("  log            : " ++ logFile)
+  Log.notice ("  result(binary) : " ++ binFile)
+  Log.notice ("  result(text)   : " ++ showFile)
+  Log.notice ("  result(summary): " ++ summaryFile)
+  let bundles = makeBundles runConfig workingDir benchRoot uniq progEnv
+  results <- mapM (runAndReport action) bundles
+  (B.writeFile binFile . encode) (catMaybes results)
   endTime <- timeStamp
-  Log.notice ("Finished Run at   " ++ endTime)
-  Log.notice ("Logged output  to " ++ logFile)
-  Log.notice ("Logged result  to " ++ outFile)
-  Log.notice ("Logged summary to " ++ summaryFile)
+  Log.notice ("Finished Run at " ++ formatEndTime startTime endTime)
+  Log.notice ("  log            : " ++ logFile)
+  Log.notice ("  result(binary) : " ++ binFile)
+  Log.notice ("  result(text)   : " ++ showFile)
+  Log.notice ("  result(summary): " ++ summaryFile)
 
 parseArgsOrDie :: IO Opt
 parseArgsOrDie = do
@@ -59,37 +68,39 @@
         Just msg -> putStrLn msg >> exitSuccess
         Nothing  -> return opts
 
-runAndReport :: Action -> BenchmarkBundle -> IO ()
+type RunResult = Maybe FibonResult
+type RunCont a = (a -> IO RunResult)
+runAndReport :: Action -> BenchmarkBundle -> IO RunResult
 runAndReport action bundle = do
   Log.notice $ "Benchmark: "++ (bundleName bundle)++ " action="++(show action)
   case action of
-    Sanity -> run sanityCheckBundle  (const $ return ())
+    Sanity -> run sanityCheckBundle  (const $ return Nothing)
     Build  -> run buildBundle        (\(BuildData time _size) -> do
                 Log.info (printf "Build completed in %0.2f seconds" time)
+                return Nothing
               )
     Run    -> run runBundle          (\fr@(FibonResult n _bd rd) -> do
-                -- Log.notice (show rr)
                 Log.result(show fr)
                 Log.summary(printf "%s %.4f" n ((meanTime . summary) rd))
+                return (Just fr)
               )
-  return ()
   where
-  run :: Show a => ActionRunner a -> (a -> IO ()) -> IO ()
+  run :: Show a => ActionRunner a -> RunCont a -> IO RunResult
   run = runAndLogErrors bundle
 
 runAndLogErrors :: Show a
                 => BenchmarkBundle
                 -> ActionRunner a
-                -> (a -> IO ())
-                -> IO ()
+                -> RunCont a
+                -> IO RunResult
 runAndLogErrors bundle act cont = do
   result <- try (act bundle)
   -- result could fail from an IOError, or from a failure in the RunMonad
   case result of
-    Left  ioe -> logError (show (ioe :: IOError))
+    Left  ioe -> logError (show (ioe :: IOError)) >> return Nothing
     Right res ->
       case res of
-        Left  e -> logError (show e) >> return ()
+        Left  e -> logError (show e) >> return Nothing
         Right r -> cont r
    where
    name = bundleName bundle
@@ -110,11 +121,12 @@
             -> FilePath  -- ^ Working directory
             -> FilePath  -- ^ Benchmark base path
             -> String    -- ^ Unique Id
+            -> [(String, String)] -- ^ Environment variables
             -> [BenchmarkBundle]
-makeBundles rc workingDir benchRoot uniq = map bundle bms
+makeBundles rc workingDir benchRoot uniq progEnv = map bundle bms
   where
   bundle (bm, size, tune) =
-    mkBundle rc bm workingDir benchRoot uniq size tune
+    mkBundle rc bm workingDir benchRoot uniq size tune progEnv
   bms = sort
         [(bm, size, tune) |
                       size <- (sizeList rc),
@@ -140,12 +152,6 @@
   format :: Int -> String
   format d = printf "%03d.%s" d configName
 
-timeStamp :: IO String
-timeStamp = do
-  tz <- getCurrentTimeZone
-  t  <- getCurrentTime
-  return $ formatTime defaultTimeLocale "%F %T" (utcToLocalTime tz t)
-
 mergeConfigOpts :: RunConfig -> Opt -> RunConfig
 mergeConfigOpts rc opt = rc {
       tuneList   = maybe (tuneList rc) (:[]) (optTuneSetting opt)
@@ -153,6 +159,25 @@
     , runList    = maybe (runList  rc)   id  (optBenchmarks  opt)
     , iterations = maybe (iterations rc) id  (optIterations  opt)
   }
+
+type TimeStamp = (ClockTime, LocalTime)
+timeStamp :: IO TimeStamp
+timeStamp = do
+  tz <- getCurrentTimeZone
+  t  <- getCurrentTime
+  ct <- getClockTime
+  return $ (ct, utcToLocalTime tz t)
+
+prettyTimeStamp :: TimeStamp -> String
+prettyTimeStamp (_,lt) = formatTime defaultTimeLocale "%F %T" lt
+
+prettyTimeDiff :: TimeStamp -> TimeStamp -> String
+prettyTimeDiff (ct1,_) (ct2,_) =
+  timeDiffToString . normalizeTimeDiff $ diffClockTimes ct2 ct1
+
+formatEndTime :: TimeStamp -> TimeStamp -> String
+formatEndTime startT endT =
+  prettyTimeStamp endT ++ " (completed in " ++ prettyTimeDiff startT endT ++")"
 
 {-
 dumpConfig :: RunConfig -> IO ()
