diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+Copyright (c) 2009, Thorkil Naur
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the author nor the names of his 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
+HOLDER 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/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,257 @@
+=======================================================================
+README: hpc-strobe: Hpc-generated strobes for a running Haskell program
+=======================================================================
+
+hpc-strobe is a rudimentary library that demonstrates the possibility of
+using Hpc (Haskell Program Coverage) to inspect the state of a running
+Haskell program. Please refer to
+
+  Andy Gill and Colin Runciman: "Haskell Program Coverage", in
+  Haskell Workshop, ACM Press, 2007
+
+for a description of Hpc. At the time of writing this (2009-May-08),
+the paper is available at
+
+  http://www.ittc.ku.edu/~andygill/papers/Hpc07.pdf
+
+In ordinary use of Hpc, a single so-called tix file is produced at the
+end of a run. The tix file records how many times each expression has
+been used during the run. This can be used to mark up the source code,
+identifying expressions that have not been used.
+
+hpc-strobe uses the basic machinery provided by Hpc to produce multiple
+tix files, also called strobes, representing the coverage at different
+times while the program is running. By subtracting such two tix files,
+again using Hpc machinery, a tix file representing the expressions used
+between the times of recording the subtracted tix files is produced.
+This may be used, for example, to get a better idea of what a
+long-running program is doing. It could also be used as a profiling
+tool, getting information about how many times individual expressions
+are used.
+
+A program is included whose strobe differences produce a crude rendering
+of an analog clock when they are used to mark up the source code using
+Hpc.
+
+Use of the library involves a simple change of the main function and
+also requires the program to be enabled for hpc. At the time of writing,
+this means using a fairly recent version of GHC and compiling the
+Haskell code with the -fhpc option.
+
+In the rest of this README, please find (1) download information; (2)
+build and install information; (3) information on how to run the
+demonstration program and render the analog clock; (4) a bit of
+background information; and (5) some final remarks. Information on how
+to use the library can be found in the haddock documentation which is
+based on comments in src/Trace/Hpc/Strobe.hs in the package.
+
+1. Downloading hpc-strobe
+-------------------------
+
+hpc-strobe is on hackage, so for example:
+
+  $ wget http://hackage.haskell.org/packages/archive/hpc-strobe/0.1/hpc-strobe-0.1.tar.gz
+
+2. Building and installing hpc-strobe
+-------------------------------------
+
+First unpack the package:
+
+  $ tar xvz hpc-strobe-0.1.tar.gz
+
+Then build and install the Cabal way:
+
+  $ cd hpc-strobe-0.1
+  $ runhaskell Setup.hs configure # Additional options may be used
+  $ runhaskell Setup.hs build
+  $ runhaskell Setup.hs haddock # Optional
+  $ runhaskell Setup.hs install # Privileges (sudo) may be needed
+
+For example:
+
+  $ tar xvfz ../../test/hpc/hpc-strobeDarcsRepository/hpc-strobe/dist/hpc-strobe-0.1.tar.gz 
+  hpc-strobe-0.1/
+  hpc-strobe-0.1/demonstration/
+  hpc-strobe-0.1/demonstration/showClock1.sh
+  hpc-strobe-0.1/demonstration/StrobeClock.hs
+  hpc-strobe-0.1/demonstration/strobeHpcDiff1.sh
+  hpc-strobe-0.1/hpc-strobe.cabal
+  hpc-strobe-0.1/LICENSE
+  hpc-strobe-0.1/README
+  hpc-strobe-0.1/Setup.hs
+  hpc-strobe-0.1/src/
+  hpc-strobe-0.1/src/Trace/
+  hpc-strobe-0.1/src/Trace/Hpc/
+  hpc-strobe-0.1/src/Trace/Hpc/Strobe.hs
+  $ cd hpc-strobe-0.1/
+  $ runhaskell Setup.hs configure --user --prefix=/Users/thorkilnaur/tn/install/hpc-strobe-0.1
+  Configuring hpc-strobe-0.1...
+  $ runhaskell Setup.hs build
+  Preprocessing library hpc-strobe-0.1...
+  Building hpc-strobe-0.1...
+  [1 of 1] Compiling Trace.Hpc.Strobe ( src/Trace/Hpc/Strobe.hs, dist/build/Trace/Hpc/Strobe.o )
+  ar: creating archive dist/build/libHShpc-strobe-0.1.a
+  $ runhaskell Setup.hs haddock
+  Preprocessing library hpc-strobe-0.1...
+  Running Haddock for hpc-strobe-0.1...
+  Documentation created: dist/doc/html/hpc-strobe/index.html
+  $ runhaskell Setup.hs install
+  Installing: /Users/thorkilnaur/tn/install/hpc-strobe-0.1/lib/hpc-strobe-0.1/ghc-6.8.2
+  Registering hpc-strobe-0.1...
+  Reading package info from "dist/installed-pkg-config" ... done.
+  Saving old package config file... done.
+  Writing new package config file... done.
+  $ 
+
+3. Running the demonstration program
+------------------------------------
+
+I show how to run he demonstration program in-place in the unpacked
+package directory:
+
+  $ cd demonstration
+  $ ghc --version
+  The Glorious Glasgow Haskell Compilation System, version 6.8.2
+  $ ghc --make StrobeClock.hs -fhpc
+  [1 of 1] Compiling Main             ( StrobeClock.hs, StrobeClock.o )
+  Linking StrobeClock ...
+  $ mkdir tixfiles
+  $ ./StrobeClock tixfiles 
+  StrobeClock(2009-May-08 10.41): Canvas pixel height 39, pixel width 39
+  StrobeClock(2009-May-08 10.41): 634
+  StrobeClock(2009-May-08 10.41): 1266
+  ...
+
+StrobeClock never stops, so at this point, enter a separate shell and
+
+  $ cd hpc-strobe-0.1/demonstration 
+  $ ls -tr tixfiles | tail -n 3
+  StrobeClock_254.tix
+  StrobeClock_255.tix
+  StrobeClock_256.tix
+  $ 
+
+to watch the growing list of strobes.
+
+Note: StrobeClock will not complain if you forget to create the tixfiles
+directory: In that case, no tixfiles will be written. Whether this
+should be considered an error or a feature, I haven't decided.
+
+To produce a single strobe difference, a shell script strobeHpcDiff1.sh
+is provided. For example:
+
+  $ sh strobeHpcDiff1.sh . tixfiles StrobeClock 0 5
+  Writing: Main.hs.html
+  Writing: hpc_index.html
+  Writing: hpc_index_fun.html
+  Writing: hpc_index_alt.html
+  Writing: hpc_index_exp.html
+  strobeHpc_StrobeClock_5_SUB_0_20090508_140251/
+  strobeHpc_StrobeClock_5_SUB_0_20090508_140251/Main.hs.html
+  $ 
+
+This deposits marked-up source code in a time-stamped directory. It
+also produces a .tar.gz file for that directory. Please look at the
+strobeHpcDiff1.sh code itself for usage information.
+
+Now point your browser to the Main.hs.html file in the time-stamped
+directory. On my Mac OS X, I can do
+
+  $ /Applications/Firefox.app/Contents/MacOS/firefox strobeHpc_StrobeClock_5_SUB_0_20090508_140251/Main.hs.html &
+  [1] 23707
+  $ 
+
+but something different may be needed. Now scroll down a few lines in
+this marked-up version of the StrobeClock.hs code to display the canvas
+function. You should be able to make out a crude rendering of an analog
+clock, showing the local time of day. And since we have taken the
+difference over 5 strobes, with 1 second between each, the seconds hand
+on the clock is smeared, covering those 5 seconds.
+
+For a more dynamic experience, with StrobeClock still running:
+
+  $ sh showClock1.sh 
+  showClock1.sh: Skip over tixfiles/StrobeClock_0.tix to tixfiles/StrobeClock_1.tix
+  showClock1.sh: Skip over tixfiles/StrobeClock_1.tix to tixfiles/StrobeClock_2.tix
+  ...
+  showClock1.sh: Skip over tixfiles/StrobeClock_30.tix to tixfiles/StrobeClock_31.tix
+  showClock1.sh: Mark up tixfiles/StrobeClock_31.tix to tixfiles/StrobeClock_32.tix
+  Writing: Main.hs.html
+  Writing: hpc_index.html
+  Writing: hpc_index_fun.html
+  Writing: hpc_index_alt.html
+  Writing: hpc_index_exp.html
+  ...
+
+This creates a directory, ClockDisplay, and maintains in this directory
+a marked-up Main.hs.html that corresponds to the difference between the
+third- and second-latest strobes in the tixfiles directory.
+(showClock1.sh assumes that the tixfiles directory is named "tixfiles"
+and also that the tixfile filename prefix is "StrobeClock".)
+
+Then point your browser to this file, for example (again after entering
+a new shell: showClock1.sh runs forever; also, I need to close the
+other firefox before starting a new one):
+
+  $ cd hpc-strobe-0.1/demonstration 
+  $ /Applications/Firefox.app/Contents/MacOS/firefox ClockDisplay/Main.hs.html &
+  [1] 24813
+  $ 
+
+This will show the most recently marked-up strobe difference, hence the
+current local time will be rendered in the canvas function. Smearing
+may occur, but refreshing the display usually helps.
+
+In addition to PPC Mac OS X 10.4 with GHC 6.8.2, the demonstration has
+been tried successfully on Windows with GHC 6.8.2 with both MSYS and
+Cygwin; and on Ubuntu x86 Linux with GHC 6.10.2.
+
+4. Background
+-------------
+
+The path to using the reflect interface in Hpc started with my desire to
+investigate a long-winding darcs pull (some GHC HEAD into GHC STABLE).
+See http://bugs.darcs.net/issue1075.  Earlier, to investigate the
+HughesPJ pretty-printing library, I had written a simple tracer that did
+a source-to-source transformation of Haskell code, inserting calls to
+Debug.Trace.trace for all top-level definitions in a Haskell module. See
+http://hackage.haskell.org/trac/ghc/ticket/1337. This was at a point in
+time where Hpc was not working. So my initial idea was to do something
+similar to darcs, transforming selected darcs modules to figure out what
+they were doing.
+
+The work started around 2008-Sep-02. After struggling for a while, I
+had settled on a modified version of the Hpc.c that comes with the GHC
+runtime system that wrote out tix files regularly. Immediately
+afterwards, however, I stumbled over the Trace.Hpc.Reflect and
+Trace.Hpc.Tix modules that supported exactly what I needed. Thanks to
+the foresight of Andy Gill and Colin Runciman, everything turned out to
+be surprisingly simple. In fact, a major motivation for publishing the
+present library is simply to make this technique better known. The
+hpc-strobe library itself is really not adding anything significant to
+Hpc itself.
+
+At the Hac5/darcs sprint 2, I gave a brief presentation of the
+technique:
+
+  http://blog.darcs.net/2009/04/darcs-hacking-sprint-2-report.html
+
+Thanks to Don Steward for helping here.
+
+5. Final words
+--------------
+
+As mentioned, the contents of the hpc-strobe library itself is really
+not particularly significant and it is easy to imagine a number of
+generalizations and variations of the technique that opens up what I
+believe is a fairly rich field of valuable applications.
+
+I should mention the hpc-tracer library by Andy Gill and Colin Runciman:
+
+  http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hpc-tracer
+
+I must admit that I have not studied this library in detail, but it
+clearly seems to be headed in much the same direction as hpc-strobe,
+but with a more elaborate user interface.
+
+Thorkil Naur
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/demonstration/StrobeClock.hs b/demonstration/StrobeClock.hs
new file mode 100644
--- /dev/null
+++ b/demonstration/StrobeClock.hs
@@ -0,0 +1,203 @@
+-- StrobeClock.hs: Demonstrate hpc-strobe by rendering a crude analog
+-- clock in the marked-up code
+-- Copyright (c) 2009, Thorkil Naur
+--
+-- Usage: ./StrobeClock tixfile-directory
+--
+-- Note: The indicated tixfile-directory must exist.
+--
+
+module Main where
+
+  import System
+  import IO
+  import Time
+  import Control.Concurrent
+  import List
+
+  import Trace.Hpc.Strobe
+
+  progName = "StrobeClock"
+  progStamp = "2009-May-08 17.26"
+
+  -- The clock will be rendered in the following part of the code. The
+  -- number of lines and their width may be adjusted; the width of the
+  -- shortest line will determine the width of the clock.
+
+  canvas x
+    = [
+          [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+        , [x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]
+      ]
+
+  -- Canvas dimensions:
+
+  pixelHeight = (length $ canvas 0) - 1
+  pixelWidth = minimum $ map ((subtract 1) . length) $ canvas 0
+
+  -- Defines the shape of pixels: To calibrate, measure the height and
+  -- width of a square part of the canvas as rendered and enter the
+  -- ratio here:
+
+  pixelHeightDividedByWidth = 16.2/17.4
+
+  -- World coordinate system is such that a 2x2 square with (0,0) in its
+  -- center fits exactly inside the canvas rectangle:
+
+  worldDimensions
+    = let
+        rawDimensions = [1.0,pixelHeightDividedByWidth]
+      in
+        map ((*2.0) . (/(minimum rawDimensions))) rawDimensions
+
+  worldLowerLeftCorner = map (negate . (/2.0)) worldDimensions
+
+  -- Converting between coordinate systems:
+
+  canvasToWorld [row,col]
+    = zipWith (+) worldLowerLeftCorner $ zipWith (*) worldDimensions
+        [fromIntegral col / fromIntegral pixelWidth,
+          1.0 - fromIntegral row / fromIntegral pixelHeight]
+
+  worldToCanvas wcs
+    = let
+        [c0,r0]
+          = zipWith (/) (zipWith (-) wcs worldLowerLeftCorner)
+              worldDimensions
+      in
+        [round $ (1.0 - r0) * fromIntegral pixelHeight,
+          round $ c0 * fromIntegral pixelWidth]
+
+  -- Shade outside unit circle:
+
+  circleShade
+    = filter ((>1.0) . sum . map (^2) . canvasToWorld)
+        [ [row,col] | row <- [0..pixelHeight], col <- [0..pixelWidth] ]
+
+  -- Line:
+
+  canvasLine [r1,c1] [r2,c2]
+    = if abs (r2 - r1) > abs (c2 - c1) then
+        map reverse $ canvasLine [c1,r1] [c2,r2]
+      else
+        if abs (c2 - c1) > 0 then
+          let
+            [(c1',r1'),(c2',r2')] = sort [(c1,r1),(c2,r2)]
+          in
+            [ [r,c] | c <- [c1'..c2'],
+              let r = r1' + (round $ fromIntegral (r2' - r1')
+                              * fromIntegral (c - c1')
+                              / fromIntegral (c2' - c1')) ]
+        else
+          [[r1,c1]]
+
+  worldLine [x1,y1] [x2,y2]
+    = canvasLine (worldToCanvas [x1,y1]) (worldToCanvas [x2,y2])
+
+  -- Piece of radial line, angle measured in degrees from vertical,
+  -- clockwise:
+
+  worldRadial angle from to
+    = let
+        radians = (90.0 - angle) / 180.0 * pi
+        [p1,p2]
+          = map (\t -> map (*t) [cos radians,sin radians]) [from,to]
+      in
+        worldLine p1 p2
+
+  -- Clock:
+
+  worldClockFixed
+    = concat [ worldRadial (fromIntegral a) 0.9 1.0
+               | a <- [30,60..360] ]
+      ++ concat [ worldRadial (fromIntegral a) 0.8 1.0
+                  | a <- [90,180..360] ]
+      ++ circleShade
+
+  worldClockVariable h m s
+    = concat [ worldRadial ah 0.0 0.55 ]
+      ++ concat [ worldRadial (ah+4.0) 0.0 0.45 ]
+      ++ concat [ worldRadial (ah-4.0) 0.0 0.45 ]
+      ++ concat [ worldRadial am 0.0 0.9 ]
+      ++ concat [ worldRadial (am-2.5) 0.0 0.8 ]
+      ++ concat [ worldRadial (am+2.5) 0.0 0.8 ]
+      ++ concat [ worldRadial as (-0.15) 1.0 ]
+      where
+      as = fromIntegral s * (360.0/60.0)
+      m' = fromIntegral m + fromIntegral s / 60.0
+      am = m'*(360/60.0)
+      ah = (fromIntegral h + m'/60.0)*(360.0/12.0)
+
+  main'
+    = do
+        putStrLn $
+          progName ++ "(" ++ progStamp ++ "): Canvas pixel height "
+            ++ show pixelHeight ++ ", pixel width " ++ show pixelWidth
+        mapM_
+          (\n ->
+            do
+              clTime <- getClockTime
+              localTime@(CalendarTime{ctHour = hr,
+                ctMin = mn, ctSec = sc}) <- toCalendarTime clTime
+              let
+                timeStamp = calendarTimeToString localTime
+                in
+                  do
+                    putStrLn $ progName ++ "(" ++ progStamp ++ "): "
+                      ++ (show $
+                            sum [ ((canvas n)!!i)!!j
+                                  | [i,j] <- worldClockFixed
+                                     ++ worldClockVariable hr mn sc ])
+              threadDelay 950000
+          ) [1..]
+
+  mainArgsInterpret [tixfileDirectory]
+    = withStrobesWrittenRegularly tixfileDirectory progName 1000000
+        main'
+
+  mainArgsInterpret args
+    = error $ "Usage: \"./" ++ progName ++ " tixfile-directory\""
+
+  main
+    = do
+        hSetBuffering stdout NoBuffering
+        args <- getArgs
+        mainArgsInterpret args
diff --git a/demonstration/showClock1.sh b/demonstration/showClock1.sh
new file mode 100644
--- /dev/null
+++ b/demonstration/showClock1.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+# showClock1.sh: Show latest difference between clock tix
+#   sh showClock1.sh
+# 2009-Apr-27 21.00 / TN
+
+PREFIX=tixfiles/StrobeClock_
+
+CURRENT=0
+
+mkdir -p ClockDisplay
+
+while true; do
+
+  NEXT=`expr $CURRENT + 1`
+  AFTER=`expr $NEXT + 1`
+
+  while [ ! -f ${PREFIX}${AFTER}.tix ]; do echo $0: Waiting for ${PREFIX}${AFTER}.tix; sleep 1; done
+
+  TWOAFTER=`expr $AFTER + 1`
+
+  if [ -f ${PREFIX}${TWOAFTER}.tix ]; then
+
+    echo $0: Skip over ${PREFIX}${CURRENT}.tix to ${PREFIX}${NEXT}.tix
+
+  else
+
+    echo $0: Mark up ${PREFIX}${CURRENT}.tix to ${PREFIX}${NEXT}.tix
+
+    hpc combine --function=SUB --output=showClock1.tix ${PREFIX}${NEXT}.tix ${PREFIX}${CURRENT}.tix
+
+    hpc markup --highlight-covered showClock1.tix
+
+    mv Main.hs.html ClockDisplay/
+
+  fi
+
+  CURRENT=$NEXT
+
+done
diff --git a/demonstration/strobeHpcDiff1.sh b/demonstration/strobeHpcDiff1.sh
new file mode 100644
--- /dev/null
+++ b/demonstration/strobeHpcDiff1.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+# strobeHpcDiff1.sh: Difference between tix strobe files 1
+#   sh strobeHpcDiff1.sh source-directory strobe-tix-directory strobe-tix-file-suffix strobe-from strobe-to
+# 2008-Sep-14 11.57 / TN
+# 2009-May-08 17.43 / TN: Replace "==" by "=" in tests
+
+COUNT=0
+for F in *.html; do
+  if [ -e "$F" ]; then
+    COUNT=`expr $COUNT + 1`
+    echo 1>&2 $0: Found .html file \"$F\"
+  fi
+done
+
+if [ "$COUNT" != 0 ]; then
+  echo 1>&2 $0: Please clean out .html files
+  exit 1
+fi
+
+if [ "$#" = "0" ]; then
+  echo 1>&2 $0: Please specify source-directory parameter
+  exit 1
+fi
+SOURCE_DIRECTORY="$1"
+shift
+
+if [ "$#" = "0" ]; then
+  echo 1>&2 $0: Please specify strobe-tix-directory parameter
+  exit 1
+fi
+STROBE_TIX_DIRECTORY="$1"
+shift
+
+if [ "$#" = "0" ]; then
+  echo 1>&2 $0: Please specify strobe-tix-file-suffix parameter
+  exit 1
+fi
+STROBE_TIX_FILE_SUFFIX="$1"
+shift
+
+if [ "$#" = "0" ]; then
+  echo 1>&2 $0: Please specify strobe-from parameter
+  exit 1
+fi
+STROBE_FROM="$1"
+shift
+
+if [ "$#" = "0" ]; then
+  echo 1>&2 $0: Please specify strobe-to parameter
+  exit 1
+fi
+STROBE_TO="$1"
+shift
+
+if [ "$#" != 0 ]; then
+  echo 1>&2 $0: There are $# superfluous parameters: "$@"
+  exit 1
+fi
+
+STROBE_TIX_SUFFIX=${STROBE_TIX_DIRECTORY}/${STROBE_TIX_FILE_SUFFIX}_
+STROBE_TIX_OUTPUT=${STROBE_TIX_FILE_SUFFIX}_${STROBE_TO}_SUB_${STROBE_FROM}
+STROBE_TIX_OUTPUT_FILE=${STROBE_TIX_OUTPUT}.tix
+
+hpc combine --function=SUB --output=${STROBE_TIX_OUTPUT_FILE} ${STROBE_TIX_SUFFIX}${STROBE_TO}.tix ${STROBE_TIX_SUFFIX}${STROBE_FROM}.tix
+RC="$?"
+if [ "$RC" != 0 ]; then
+  echo 1>&2 $0: hpc combine: Unexpected return code $RC
+  exit 1
+fi
+
+hpc markup --highlight-covered --srcdir=${SOURCE_DIRECTORY} ${STROBE_TIX_OUTPUT_FILE}
+RC="$?"
+if [ "$RC" != 0 ]; then
+  echo 1>&2 $0: hpc combine: Unexpected return code $RC
+  exit 1
+fi
+
+WORKING_DIR=strobeHpc_${STROBE_TIX_OUTPUT}_`date +%Y%m%d_%H%M%S`
+
+mkdir ${WORKING_DIR}
+RC="$?"
+if [ "$RC" != 0 ]; then
+  echo 1>&2 $0: mkdir ${WORKING_DIR}: Unexpected return code $RC
+  exit 1
+fi
+
+mv `grep -l '"istickedoff"' *.html` ${WORKING_DIR}
+RC="$?"
+if [ "$RC" != 0 ]; then
+  echo 1>&2 $0: mv `grep -l '"istickedoff"' ${WORKING_DIR}/*.html` .: Unexpected return code $RC
+  exit 1
+fi
+
+tar cvzf ${WORKING_DIR}.tar.gz ${WORKING_DIR}
+
+rm *.html
+
+# Exit OK:
+
+exit 0
diff --git a/hpc-strobe.cabal b/hpc-strobe.cabal
new file mode 100644
--- /dev/null
+++ b/hpc-strobe.cabal
@@ -0,0 +1,41 @@
+Name:               hpc-strobe
+Version:            0.1
+Synopsis:           Hpc-generated strobes for a running Haskell program
+License:            BSD3
+License-file:       LICENSE
+Author:             Thorkil Naur
+Maintainer:         naur@post11.tele.dk
+Build-Type:         Simple
+Cabal-Version:      >=1.2
+Description:        A rudimentary library that demonstrates the
+                    possibility of using Hpc (Haskell Program Coverage)
+                    to inspect the state of a running Haskell program.
+                    Use of the library involves a simple change of the
+                    main function and also requires the program to be
+                    enabled for hpc. At the time of writing, this means
+                    using a fairly recent version of GHC and compiling
+                    the Haskell code with the @-fhpc@ option.
+Category:           Trace, Debug
+extra-source-files: README
+                    demonstration/StrobeClock.hs
+                    demonstration/strobeHpcDiff1.sh
+                    demonstration/showClock1.sh
+
+Library
+  Build-Depends:    base, hpc, filepath
+  Exposed-modules:  Trace.Hpc.Strobe
+  hs-source-dirs:   src
+  ghc-options:      -Wall
+
+--
+-- Note: Checking the package on
+-- http://hackage.haskell.org/packages/upload.html reports:
+--
+--   Exposed modules use unallocated top-level names: Trace
+--
+-- I feel somewhat justified in keeping this name, since the hpc
+-- package itself uses Trace.Hpc.Tix and Trace.Hpc.Reflect. But I am
+-- certainly open to suggested alternative names.
+--
+-- Regards Thorkil
+--
diff --git a/src/Trace/Hpc/Strobe.hs b/src/Trace/Hpc/Strobe.hs
new file mode 100644
--- /dev/null
+++ b/src/Trace/Hpc/Strobe.hs
@@ -0,0 +1,79 @@
+------------------------------------------------------------------------
+-- |
+-- Module      : Trace.Hpc.Strobe
+-- Copyright   : (C) 2009, Thorkil Naur
+-- License     : BSD3-style (see LICENSE)
+--
+-- Maintainer  : Thorkil Naur
+-- Stability   : unstable
+-- Portability : Requires GHC with Hpc support.
+--
+-- A rudimentary library that demonstrates the possibility of
+-- using Hpc (Haskell Program Coverage) to inspect the state of
+-- a running Haskell program. Use of the library involves a
+-- simple change of the main function and also requires the
+-- program to be enabled for hpc. At the time of writing, this
+-- means using a fairly recent version of GHC and compiling the
+-- Haskell code with the @-fhpc@ option.
+--
+------------------------------------------------------------------------
+
+module Trace.Hpc.Strobe (
+
+    -- * Write strobes (tix files) regularly while program is running
+      withStrobesWrittenRegularly
+
+  ) where
+
+import System.FilePath
+import Control.Concurrent
+import Trace.Hpc.Tix
+import Trace.Hpc.Reflect
+
+strobe :: FilePath -> String -> Int -> IO ()
+strobe directory filePrefix interval
+  = do mapM_ go [0..]
+    where
+    go :: Integer -> IO ()
+    go d = do strobeTix d
+              threadDelay interval
+    fileName n = (filePrefix ++ "_" ++ show n) <.> "tix"
+    strobeTix n = do tix <- examineTix
+                     writeTix (directory </> fileName n) tix
+
+-- | Replace
+--
+-- @
+-- main = \<your main function>
+-- @
+--
+-- by
+--
+-- @
+-- myMain = \<your main function>
+-- main = withStrobesWrittenRegularly
+--          \"\<tixfile directory>\"
+--          \"myMain\"
+--          1000000
+--          myMain
+-- @
+--
+-- and strobes (separate Hpc tix files) will be written regularly,
+-- with 1 second (1000000 microseconds) between each writing of a
+-- strobe. The tix files will be deposited in the indicated tixfile
+-- directory and be named \"myMain_\<index>.tix\" where the
+-- index is taken from [0..].
+
+withStrobesWrittenRegularly
+  :: FilePath     -- ^ Name of directory where .tix files are deposited.
+                  -- If this directory does not exist, no tix files are
+                  -- written.
+  -> String       -- ^ Prefix of file name for .tix files.
+  -> Int          -- ^ Microseconds between writing a .tix file.
+  -> IO ()        -- ^ The main function to be strobe'd.
+  -> IO ()        -- ^ The modified main function.
+
+withStrobesWrittenRegularly directory filePrefix interval mainFunction
+  = do
+      forkIO $ strobe directory filePrefix interval
+      mainFunction
