diff --git a/Tools/StatePlot.hs b/Tools/StatePlot.hs
--- a/Tools/StatePlot.hs
+++ b/Tools/StatePlot.hs
@@ -1,16 +1,19 @@
 module Main where
 
+import System (getArgs)
+import System.Exit
+
 import Control.Monad.Writer
 import Control.Monad.State
 import qualified Data.Map as M
 import Data.List
 import Data.Ord
 import Data.Function
-import Debug.Trace
 import Data.Maybe
+
 import Data.Time
 import Data.Time.Parse
-import System (getArgs)
+
 import qualified Data.ByteString.Char8 as B
 import Graphics.Rendering.Chart
 import Graphics.Rendering.Chart.Renderable
@@ -78,7 +81,7 @@
         }
       let drawBar i (ms1, ms2, color) = do {
           setLineStyle $ solidLine 1 transparent
-        ; setFillStyle $ solidFillStyle $ opaque $ fromMaybe (error "unknown color") (readColourName color)
+        ; setFillStyle $ solidFillStyle $ opaque $ fromMaybe (error $ "unknown color: " ++ color) (readColourName color)
         ; fillPath (rectPath $ Rect (Point (ms2x ms1) (track2y i)) (Point (ms2x ms2) (track2y i + bandHeight)))
         }
       let drawTrack (i, es) = mapM_ (drawBar i) (bars es)
@@ -96,13 +99,42 @@
       mapM_ drawTrack $ zip [0..] tracks
       return nullPickFn
 
+showHelp = mapM_ putStrLn [
+    "splot - a tool for visualizing the lifecycle of many concurrent multi-stage processes. See http://www.haskell.org/haskellwiki/Splot",
+    "Usage: splot [-o PNGFILE] [-w WIDTH] [-h HEIGHT] [-bh BARHEIGHT] [-tf TIMEFORMAT]",
+    "             [-tickInterval TICKINTERVAL]",
+    "  -o PNGFILE    - filename to which the output will be written in PNG format.",
+    "                  If omitted, it will be shown in a window.",
+    "  -w, -h        - width and height of the resulting picture. Default 640x480.",
+    "  -bh           - height of the bar depicting each individual process. Default 5 pixels.",
+    "                  Use 1 or so if you have a lot of them.",
+    "  -tf           - time format, as in http://linux.die.net/man/3/strptime but with ",
+    "                  fractional seconds supported via %OS - will parse 12.4039 or 12,4039",
+    "  -tickInterval - ticks on the X axis will be this often (in millis).",
+    "",
+    "Input is read from stdin. Example input (speaks for itself):",
+    "2010-10-21 16:45:09,431 >foo green",
+    "2010-10-21 16:45:09,541 >bar green",
+    "2010-10-21 16:45:10,631 >foo yellow",
+    "2010-10-21 16:45:10,725 >foo red",
+    "2010-10-21 16:45:10,930 >bar blue",
+    "2010-10-21 16:45:11,322 <foo",
+    "2010-10-21 16:45:12,508 <bar",
+    "",
+    "'>FOO COLOR' means 'start a bar of color COLOR on track FOO',",
+    "'<FOO' means 'end the current bar for FOO'."
+    ]
+
 main = do
   args <- getArgs
+  case args of
+    ["--help"] -> showHelp >> exitSuccess
+    _          -> return ()
   let (w,h) = (read $ getArg "w" "640" args, read $ getArg "h" "480" args)
   let bandHeight = read $ getArg "bh" "5" args
   let ticksIntervalMs = read $ getArg "tickInterval" "10" args
   let timeFormat = getArg "tf" "%Y-%m-%d %H:%M:%OS" args
-  let parseTime = fromMaybe (error "Invalid time") . strptime (B.pack timeFormat)
+  let parseTime s = fromMaybe (error $ "Invalid time: " ++ show s) . strptime (B.pack timeFormat) $ s
   let outPNG = getArg "o" "" args
   input <- B.getContents
   let events = parse parseTime `map` B.lines input
diff --git a/splot.cabal b/splot.cabal
--- a/splot.cabal
+++ b/splot.cabal
@@ -1,5 +1,5 @@
 Name: splot
-Version: 0.1.0
+Version: 0.1.1
 License: BSD3
 License-file: LICENSE
 Copyright: Eugene Kirpichov, 2010
@@ -9,6 +9,7 @@
 Description: A tool for visualizing the lifecycle of many concurrent multi-staged processes.
   Each process has a name, it starts at a point in time, ends at a point in time, and at some
   points in time it changes colour.
+Homepage: http://www.haskell.org/haskellwiki/Splot
 Category: Graphics
 Cabal-Version: >= 1.6
 Build-Type: Simple
