diff --git a/HUnit.cabal b/HUnit.cabal
--- a/HUnit.cabal
+++ b/HUnit.cabal
@@ -1,20 +1,25 @@
-name:		HUnit
-version:	1.2.0.0
-license:	BSD3
-license-file:	LICENSE
-author:		Dean Herington
-homepage:	http://hunit.sourceforge.net/
-category:	Testing
-build-depends:	base
-synopsis:	A unit testing framework for Haskell
+name:           HUnit
+version:        1.2.0.1
+license:        BSD3
+license-file:   LICENSE
+author:         Dean Herington
+homepage:       http://hunit.sourceforge.net/
+category:       Testing
+synopsis:       A unit testing framework for Haskell
+maintainer:     libraries@haskell.org
+cabal-version:  >= 1.2
 description:
-	HUnit is a unit testing framework for Haskell, inspired by the
-	JUnit tool for Java, see: <http://www.junit.org>.
+        HUnit is a unit testing framework for Haskell, inspired by the
+        JUnit tool for Java, see: <http://www.junit.org>.
 build-type:     Simple
-exposed-modules:
-	Test.HUnit.Base,
-	Test.HUnit.Lang,
-	Test.HUnit.Terminal,
-	Test.HUnit.Text,
-	Test.HUnit
-extensions:	CPP
+
+Library
+    build-depends: base
+    exposed-modules:
+        Test.HUnit.Base,
+        Test.HUnit.Lang,
+        Test.HUnit.Terminal,
+        Test.HUnit.Text,
+        Test.HUnit
+    extensions: CPP
+
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,12 @@
+HUnit is a unit testing framework for Haskell, inspired by the JUnit
+tool for Java.  HUnit is free software; see its "License" file for
+details.  HUnit is available at <http://hunit.sourceforge.net>.
+
+HUnit 1.1.1 consists of a number of files.  Besides Haskell source files
+in Test/HUnit (whose names end in ".hs" or ".lhs"), these files include:
+
+  * README          -- this file
+  * doc/Guide.html  -- user's guide, in HTML format
+  * LICENSE         -- license for use of HUnit
+
+See the user's guide for more information.
diff --git a/Test/HUnit/Lang.lhs b/Test/HUnit/Lang.lhs
--- a/Test/HUnit/Lang.lhs
+++ b/Test/HUnit/Lang.lhs
@@ -20,7 +20,7 @@
 > import Data.List (isPrefixOf)
 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
 > import Data.Dynamic
-> import Control.Exception as E         ( throwDyn, try, Exception(..) )
+> import Control.Exception as E
 #else
 > import System.IO.Error (ioeGetErrorString, try)
 #endif
@@ -52,7 +52,10 @@
 
 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
 > data HUnitFailure = HUnitFailure String
+>     deriving Show
 >
+> instance Exception HUnitFailure
+>
 > hunitFailureTc :: TyCon
 > hunitFailureTc = mkTyCon "HUnitFailure"
 > {-# NOINLINE hunitFailureTc #-}
@@ -60,17 +63,14 @@
 > instance Typeable HUnitFailure where
 >     typeOf _ = mkTyConApp hunitFailureTc []
 
-> assertFailure msg = E.throwDyn (HUnitFailure msg)
+> assertFailure msg = E.throw (HUnitFailure msg)
 
 > performTestCase action = 
->     do r <- E.try action
->        case r of 
->          Right () -> return Nothing
->          Left e@(E.DynException dyn) -> 
->              case fromDynamic dyn of
->                Just (HUnitFailure msg) -> return $ Just (True, msg)
->                Nothing                 -> return $ Just (False, show e)
->          Left e -> return $ Just (False, show e)
+>     do action
+>        return Nothing
+>      `E.catches`
+>        [E.Handler (\(HUnitFailure msg) -> return $ Just (True, msg)),
+>         E.Handler (\e -> return $ Just (False, show (e :: E.SomeException)))]
 #else
 > hunitPrefix = "HUnit:"
 
diff --git a/doc/Guide.html b/doc/Guide.html
new file mode 100644
--- /dev/null
+++ b/doc/Guide.html
@@ -0,0 +1,711 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+  <meta name="Author" content="Dean Herington">
+  <meta name="KeyWords" content="HUnit, unit testing, test-first development, Haskell, JUnit">
+  <meta name="Content-Type" content="text/html; charset=iso-8859-1">
+  <title>HUnit 1.0 User's Guide</title>
+</head>
+<body>
+
+<h1>HUnit 1.0 User's Guide</h1>
+
+HUnit is a unit testing framework for Haskell, inspired by the JUnit
+tool for Java. This guide describes how to use HUnit, assuming
+you are familiar with Haskell, though not necessarily with
+JUnit. You can obtain HUnit, including this guide, at
+<a href="http://hunit.sourceforge.net">http://hunit.sourceforge.net</a>.
+
+<h2>Introduction</h2>
+
+A test-centered methodology for software development is most effective
+when tests are easy to create, change, and execute. The <a
+href="http://www.junit.org">JUnit</a> tool pioneered support for
+test-first development in <a href="http://java.sun.com">Java</a>.
+HUnit is an adaptation of JUnit to Haskell, a general-purpose, purely
+functional programming language. (To learn more about Haskell,
+see <a href="http://www.haskell.org">http://www.haskell.org</a>.)
+<p>
+With HUnit, as with JUnit, you can easily create tests, name them,
+group them into suites, and execute them, with the framework checking
+the results automatically. Test specification in HUnit is even
+more concise and flexible than in JUnit, thanks to the nature of the
+Haskell language. HUnit currently includes only a text-based
+test controller, but the framework is designed for easy
+extension. (Would anyone care to write a graphical test
+controller for HUnit?)
+<p>
+The next section helps you get started using HUnit in simple
+ways. Subsequent sections give details on <a
+href="#WritingTests">writing tests</a> and <a
+href="#RunningTests">running tests</a>. The document concludes
+with a section describing HUnit's <a
+href="#ConstituentFiles">constituent files</a> and a section giving
+<a href="#References">references</a> to further information.
+
+<h2><a name="GettingStarted">Getting Started</a></h2>
+
+In the Haskell module where your tests will reside, import module
+<tt>Test.HUnit</tt>:
+<pre>
+    import Test.HUnit
+</pre>
+Define test cases as appropriate:
+<pre>
+    test1 = TestCase (assertEqual "for (foo 3)," (1,2) (foo 3))
+    test2 = TestCase (do (x,y) &lt;- partA 3
+                         assertEqual "for the first result of partA," 5 x
+                         b &lt;- partB y
+                         assertBool ("(partB " ++ show y ++ ") failed") b)
+</pre>
+Name the test cases and group them together:
+<pre>
+    tests = TestList [TestLabel "test1" test1, TestLabel "test2" test2]
+</pre>
+Run the tests as a group. At a Haskell interpreter prompt, apply
+the function <tt>runTestTT</tt> to the collected tests. (The
+"<tt>TT</tt>" suggests <b><u>t</u></b>ext orientation with output to
+the <b><u>t</u></b>erminal.)
+<pre>
+    > runTestTT tests
+    Cases: 2  Tried: 2  Errors: 0  Failures: 0
+    >
+</pre>
+If the tests are proving their worth, you might see:
+<pre>
+    > runTestTT tests
+    ### Failure in: 0:test1
+    for (foo 3),
+    expected: (1,2)
+     but got: (1,3)
+    Cases: 2  Tried: 2  Errors: 0  Failures: 1
+    >
+</pre>
+Isn't that easy?
+<p>
+You can specify tests even more succinctly using operators and
+overloaded functions that HUnit provides:
+<pre>
+    tests = test [ "test1" ~: "(foo 3)" ~: (1,2) ~=? (foo 3),
+                   "test2" ~: do (x, y) &lt;- partA 3
+                                 assertEqual "for the first result of partA," 5 x
+                                 partB y @? "(partB " ++ show y ++ ") failed" ]
+</pre>
+Assuming the same test failures as before, you would see:
+<pre>
+    > runTestTT tests
+    ### Failure in: 0:test1:(foo 3)
+    expected: (1,2)
+     but got: (1,3)
+    Cases: 2  Tried: 2  Errors: 0  Failures: 1
+    >
+</pre>
+
+<h2><a name="WritingTests"></a>Writing Tests</h2>
+
+Tests are specified compositionally. <a
+href="#Assertions">Assertions</a> are combined to make a <a
+href="#TestCase">test case</a>, and test cases are combined into <a
+href="#Tests">tests</a>. HUnit also provides <a
+href="#AdvancedFeatures">advanced features</a> for more convenient
+test specification.
+
+<h3><a name="Assertions"></a>Assertions</h3>
+
+The basic building block of a test is an <b>assertion</b>.
+<pre>
+    type Assertion = IO ()
+</pre>
+An assertion is an <tt>IO</tt> computation that always produces a void
+result. Why is an assertion an <tt>IO</tt> computation?  So that
+programs with real-world side effects can be tested. How does an
+assertion assert anything if it produces no useful result?  The answer
+is that an assertion can signal failure by calling
+<tt>assertFailure</tt>.
+<pre>
+    assertFailure :: String -> Assertion
+    assertFailure msg = ioError (userError ("HUnit:" ++ msg))
+</pre>
+<tt>(assertFailure msg)</tt> raises an exception. The string
+argument identifies the failure. The failure message is prefixed
+by "<tt>HUnit:</tt>" to mark it as an HUnit assertion failure
+message. The HUnit test framework interprets such an exception
+as indicating failure of the test whose execution raised the
+exception. (Note: The details concerning the implementation of
+<tt>assertFailure</tt> are subject to change and should not be relied
+upon.)
+<p>
+<tt>assertFailure</tt> can be used directly, but it is much more
+common to use it indirectly through other assertion functions that
+conditionally assert failure.
+<pre>
+    assertBool :: String -> Bool -> Assertion
+    assertBool msg b = unless b (assertFailure msg)
+
+    assertString :: String -> Assertion
+    assertString s = unless (null s) (assertFailure s)
+
+    assertEqual :: (Eq a, Show a) => String -> a -> a -> Assertion
+    assertEqual preface expected actual =
+      unless (actual == expected) (assertFailure msg)
+     where msg = (if null preface then "" else preface ++ "\n") ++
+                 "expected: " ++ show expected ++ "\n but got: " ++ show actual
+</pre>
+With <tt>assertBool</tt> you give the assertion condition and failure
+message separately. With <tt>assertString</tt> the two are
+combined. With <tt>assertEqual</tt> you provide a "preface", an
+expected value, and an actual value; the failure message shows the two
+unequal values and is prefixed by the preface. Additional ways
+to create assertions are described later under <a
+href="#AdvancedFeatures">Advanced Features</a>.
+<p>
+Since assertions are <tt>IO</tt> computations, they may be
+combined--along with other <tt>IO</tt> computations--using
+<tt>(>>=)</tt>, <tt>(>>)</tt>, and the <tt>do</tt> notation. As
+long as its result is of type <tt>(IO ())</tt>, such a combination
+constitutes a single, collective assertion, incorporating any number
+of constituent assertions. The important features of such a
+collective assertion are that it fails if any of its constituent
+assertions is executed and fails, and that the first constituent
+assertion to fail terminates execution of the collective
+assertion. Such behavior is essential to specifying a test case.
+
+<h3><a name="TestCase"></a>Test Case</h3>
+
+A <b>test case</b> is the unit of test execution. That is,
+distinct test cases are executed independently. The failure of
+one is independent of the failure of any other.
+<p>
+A test case consists of a single, possibly collective,
+assertion. The possibly multiple constituent assertions in a
+test case's collective assertion are <b>not</b> independent.
+Their interdependence may be crucial to specifying correct operation
+for a test. A test case may involve a series of steps, each
+concluding in an assertion, where each step must succeed in order for
+the test case to continue. As another example, a test may
+require some "set up" to be performed that must be undone ("torn down"
+in JUnit parlance) once the test is complete. In this case, you
+could use Haskell's <tt>IO.bracket</tt> function to achieve the
+desired effect.
+<p>
+You can make a test case from an assertion by applying the
+<tt>TestCase</tt> constructor. For example,
+<tt>(TestCase&nbsp;(return&nbsp;()))</tt> is a test case that never
+fails, and
+<tt>(TestCase&nbsp;(assertEqual&nbsp;"for&nbsp;x,"&nbsp;3&nbsp;x))</tt>
+is a test case that checks that the value of <tt>x</tt> is 3.&nbsp;
+Additional ways to create test cases are described later under
+<a href="#AdvancedFeatures">Advanced Features</a>.
+
+<h3><a name="Tests"></a>Tests</h3>
+
+As soon as you have more than one test, you'll want to name them to
+tell them apart. As soon as you have more than several tests,
+you'll want to group them to process them more easily. So,
+naming and grouping are the two keys to managing collections of tests.
+<p>
+In tune with the "composite" design pattern [<a
+href="#DesignPatterns">1</a>], a <b>test</b> is defined as a package
+of test cases. Concretely, a test is either a single test case,
+a group of tests, or either of the first two identified by a label.
+<pre>
+    data Test = TestCase Assertion
+              | TestList [Test]
+              | TestLabel String Test
+</pre>
+There are three important features of this definition to note:
+<ul>
+<li>
+A <tt>TestList</tt> consists of a list of tests rather than a list of
+test cases. This means that the structure of a <tt>Test</tt> is
+actually a tree. Using a hierarchy helps organize tests just as
+it helps organize files in a file system.
+</li>
+<li>
+A <tt>TestLabel</tt> is attached to a test rather than to a test
+case. This means that all nodes in the test tree, not just test
+case (leaf) nodes, can be labeled. Hierarchical naming helps
+organize tests just as it helps organize files in a file system.
+</li>
+<li>
+A <tt>TestLabel</tt> is separate from both <tt>TestCase</tt> and
+<tt>TestList</tt>. This means that labeling is optional
+everywhere in the tree. Why is this a good thing?  Because of
+the hierarchical structure of a test, each constituent test case is
+uniquely identified by its path in the tree, ignoring all
+labels. Sometimes a test case's path (or perhaps its subpath
+below a certain node) is a perfectly adequate "name" for the test case
+(perhaps relative to a certain node). In this case, creating a
+label for the test case is both unnecessary and inconvenient.
+</li>
+</ul>
+<p>
+The number of test cases that a test comprises can be computed with
+<tt>testCaseCount</tt>.
+<pre>
+    testCaseCount :: Test -> Int
+</pre>
+<p>
+As mentioned above, a test is identified by its <b>path</b> in the
+test hierarchy.
+<pre>
+    data Node  = ListItem Int | Label String
+      deriving (Eq, Show, Read)
+
+    type Path = [Node]    -- Node order is from test case to root.
+</pre>
+Each occurrence of <tt>TestList</tt> gives rise to a <tt>ListItem</tt>
+and each occurrence of <tt>TestLabel</tt> gives rise to a
+<tt>Label</tt>. The <tt>ListItem</tt>s by themselves ensure
+uniqueness among test case paths, while the <tt>Label</tt>s allow you
+to add mnemonic names for individual test cases and collections of
+them.
+<p>
+Note that the order of nodes in a path is reversed from what you might
+expect: The first node in the list is the one deepest in the
+tree. This order is a concession to efficiency: It allows common
+path prefixes to be shared.
+<p>
+The paths of the test cases that a test comprises can be computed with
+<tt>testCasePaths</tt>. The paths are listed in the order in
+which the corresponding test cases would be executed.
+<pre>
+    testCasePaths :: Test -> [Path]
+</pre>
+<p>
+The three variants of <tt>Test</tt> can be constructed simply by
+applying <tt>TestCase</tt>, <tt>TestList</tt>, and <tt>TestLabel</tt>
+to appropriate arguments. Additional ways to create tests are
+described later under <a href="#AdvancedFeatures">Advanced
+Features</a>.
+<p>
+The design of the type <tt>Test</tt> provides great conciseness,
+flexibility, and convenience in specifying tests. Moreover, the
+nature of Haskell significantly augments these qualities:
+<ul>
+<li>
+Combining assertions and other code to construct test cases is easy
+with the <tt>IO</tt> monad.
+</li>
+<li>
+Using overloaded functions and special operators (see below),
+specification of assertions and tests is extremely compact.
+</li>
+<li>
+Structuring a test tree by value, rather than by name as in JUnit,
+provides for more convenient, flexible, and robust test suite
+specification. In particular, a test suite can more easily be
+computed "on the fly" than in other test frameworks.
+</li>
+<li>
+Haskell's powerful abstraction facilities provide unmatched support
+for test refactoring.
+</li>
+</ul>
+
+<h3><a name="AdvancedFeatures"></a>Advanced Features</h3>
+
+HUnit provides additional features for specifying assertions and tests
+more conveniently and concisely. These facilities make use of
+Haskell type classes.
+<p>
+The following operators can be used to construct assertions.
+<pre>
+    infix 1 @?, @=?, @?=
+
+    (@?) :: (AssertionPredicable t) => t -> String -> Assertion
+    pred @? msg = assertionPredicate pred >>= assertBool msg
+
+    (@=?) :: (Eq a, Show a) => a -> a -> Assertion
+    expected @=? actual = assertEqual "" expected actual
+
+    (@?=) :: (Eq a, Show a) => a -> a -> Assertion
+    actual @?= expected = assertEqual "" expected actual
+</pre>
+You provide a boolean condition and failure message separately to
+<tt>(@?)</tt>, as for <tt>assertBool</tt>, but in a different
+order. The <tt>(@=?)</tt> and <tt>(@?=)</tt> operators provide
+shorthands for <tt>assertEqual</tt> when no preface is required.
+They differ only in the order in which the expected and actual values
+are provided. (The actual value--the uncertain one--goes on the
+"?" side of the operator.)
+<p>
+The <tt>(@?)</tt> operator's first argument is something from which an
+assertion predicate can be made, that is, its type must be
+<tt>AssertionPredicable</tt>.
+<pre>
+    type AssertionPredicate = IO Bool
+
+    class AssertionPredicable t
+     where assertionPredicate :: t -> AssertionPredicate
+
+    instance AssertionPredicable Bool
+     where assertionPredicate = return
+
+    instance (AssertionPredicable t) => AssertionPredicable (IO t)
+     where assertionPredicate = (>>= assertionPredicate)
+</pre>
+The overloaded <tt>assert</tt> function in the <tt>Assertable</tt>
+type class constructs an assertion.
+<pre>
+    class Assertable t
+     where assert :: t -> Assertion
+
+    instance Assertable ()
+     where assert = return
+
+    instance Assertable Bool
+     where assert = assertBool ""
+
+    instance (ListAssertable t) => Assertable [t]
+     where assert = listAssert
+
+    instance (Assertable t) => Assertable (IO t)
+     where assert = (>>= assert)
+</pre>
+The <tt>ListAssertable</tt> class allows <tt>assert</tt> to be applied
+to <tt>[Char]</tt> (that is, <tt>String</tt>).
+<pre>
+    class ListAssertable t
+     where listAssert :: [t] -> Assertion
+
+    instance ListAssertable Char
+     where listAssert = assertString
+</pre>
+With the above declarations, <tt>(assert&nbsp;())</tt>,
+<tt>(assert&nbsp;True)</tt>, and <tt>(assert&nbsp;"")</tt> (as well as
+<tt>IO</tt> forms of these values, such as <tt>(return&nbsp;())</tt>)
+are all assertions that never fail, while <tt>(assert&nbsp;False)</tt>
+and <tt>(assert&nbsp;"some&nbsp;failure&nbsp;message")</tt> (and their
+<tt>IO</tt> forms) are assertions that always fail. You may
+define additional instances for the type classes <tt>Assertable</tt>,
+<tt>ListAssertable</tt>, and <tt>AssertionPredicable</tt> if that
+should be useful in your application.
+<p>
+The overloaded <tt>test</tt> function in the <tt>Testable</tt> type
+class constructs a test.
+<pre>
+    class Testable t
+     where test :: t -> Test
+
+    instance Testable Test
+     where test = id
+
+    instance (Assertable t) => Testable (IO t)
+     where test = TestCase . assert
+
+    instance (Testable t) => Testable [t]
+     where test = TestList . map test
+</pre>
+The <tt>test</tt> function makes a test from either an
+<tt>Assertion</tt> (using <tt>TestCase</tt>), a list of
+<tt>Testable</tt> items (using <tt>TestList</tt>), or a <tt>Test</tt>
+(making no change).
+<p>
+The following operators can be used to construct tests.
+<pre>
+    infix  1 ~?, ~=?, ~?=
+    infixr 0 ~:
+
+    (~?) :: (AssertionPredicable t) => t -> String -> Test
+    pred ~? msg = TestCase (pred @? msg)
+
+    (~=?) :: (Eq a, Show a) => a -> a -> Test
+    expected ~=? actual = TestCase (expected @=? actual)
+
+    (~?=) :: (Eq a, Show a) => a -> a -> Test
+    actual ~?= expected = TestCase (actual @?= expected)
+
+    (~:) :: (Testable t) => String -> t -> Test
+    label ~: t = TestLabel label (test t)
+</pre>
+<tt>(~?)</tt>, <tt>(~=?)</tt>, and <tt>(~?=)</tt> each make an
+assertion, as for <tt>(@?)</tt>, <tt>(@=?)</tt>, and <tt>(@?=)</tt>,
+respectively, and then a test case from that assertion.
+<tt>(~:)</tt> attaches a label to something that is
+<tt>Testable</tt>. You may define additional instances for the
+type class <tt>Testable</tt> should that be useful.
+
+<h2><a name="RunningTests"></a>Running Tests</h2>
+
+HUnit is structured to support multiple test controllers. The
+first subsection below describes the <a href="#TestExecution">test
+execution</a> characteristics common to all test controllers.
+The second subsection describes the
+<a href="#Text-BasedController">text-based controller</a> that is
+included with HUnit.
+
+<h3><a name="TestExecution">Test Execution</a></h3>
+
+All test controllers share a common test execution model. They
+differ only in how the results of test execution are shown.
+<p>
+The execution of a test (a value of type <tt>Test</tt>) involves the
+serial execution (in the <tt>IO</tt> monad) of its constituent test
+cases. The test cases are executed in a depth-first,
+left-to-right order. During test execution, four counts of test
+cases are maintained:
+<pre>
+    data Counts = Counts { cases, tried, errors, failures :: Int }
+      deriving (Eq, Show, Read)
+</pre>
+<ul>
+<li>
+<tt>cases</tt> is the number of test cases included in the test.
+This number is a static property of a test and remains unchanged
+during test execution.
+</li>
+<li>
+<tt>tried</tt> is the number of test cases that have been executed so
+far during the test execution.
+</li>
+<li>
+<tt>errors</tt> is the number of test cases whose execution ended with
+an unexpected exception being raised. Errors indicate problems
+with test cases, as opposed to the code under test.
+</li>
+<li>
+<tt>failures</tt> is the number of test cases whose execution asserted
+failure. Failures indicate problems with the code under test.
+</li>
+</ul>
+Why is there no count for test case successes?  The technical reason
+is that the counts are maintained such that the number of test case
+successes is always equal to
+<tt>(tried&nbsp;-&nbsp;(errors&nbsp;+&nbsp;failures))</tt>. The
+psychosocial reason is that, with test-centered development and the
+expectation that test failures will be few and short-lived, attention
+should be focused on the failures rather than the successes.
+<p>
+As test execution proceeds, three kinds of reporting event are
+communicated to the test controller. (What the controller does
+in response to the reporting events depends on the controller.)
+<ul>
+<li>
+<i>start</i> --
+Just prior to initiation of a test case, the path of the test case and
+the current counts (excluding the current test case) are reported.
+</li>
+<li>
+<i>error</i> --
+When a test case terminates with an error, the error message is
+reported, along with the test case path and current counts (including
+the current test case).
+</li>
+<li>
+<i>failure</i> --
+When a test case terminates with a failure, the failure message is
+reported, along with the test case path and current counts (including
+the current test case).
+</li>
+</ul>
+Typically, a test controller shows <i>error</i> and <i>failure</i>
+reports immediately but uses the <i>start</i> report merely to update
+an indication of overall test execution progress.
+
+<h3><a name="Text-BasedController">Text-Based Controller</a></h3>
+
+A text-based test controller is included with HUnit.
+<pre>
+    runTestText :: PutText st -> Test -> IO (Counts, st)
+</pre>
+<tt>runTestText</tt> is generalized on a <i>reporting scheme</i> given
+as its first argument. During execution of the test given as its
+second argument, the controller creates a string for each reporting
+event and processes it according to the reporting scheme. When
+test execution is complete, the controller returns the final counts
+along with the final state for the reporting scheme.
+<p>
+The strings for the three kinds of reporting event are as follows.
+<ul>
+<li>
+A <i>start</i> report is the result of the function
+<tt>showCounts</tt> applied to the counts current immediately prior to
+initiation of the test case being started.
+</li>
+<li>
+An <i>error</i> report is of the form
+"<tt>Error&nbsp;in:&nbsp;&nbsp;&nbsp;<i>path</i>\n<i>message</i></tt>",
+where <i>path</i> is the path of the test case in error, as shown by
+<tt>showPath</tt>, and <i>message</i> is a message describing the
+error. If the path is empty, the report has the form
+"<tt>Error:\n<i>message</i></tt>".
+</li>
+<li>
+A <i>failure</i> report is of the form
+"<tt>Failure&nbsp;in:&nbsp;<i>path</i>\n<i>message</i></tt>", where
+<i>path</i> is the path of the test case in error, as shown by
+<tt>showPath</tt>, and <i>message</i> is the failure message. If
+the path is empty, the report has the form
+"<tt>Failure:\n<i>message</i></tt>".
+</li>
+</ul>
+<p>
+The function <tt>showCounts</tt> shows a set of counts.
+<pre>
+    showCounts :: Counts -> String
+</pre>
+The form of its result is
+"<tt>Cases:&nbsp;<i>cases</i>&nbsp;&nbsp;Tried:&nbsp;<i>tried</i>&nbsp;&nbsp;Errors:&nbsp;<i>errors</i>&nbsp;&nbsp;Failures:&nbsp;<i>failures</i></tt>"
+where <i>cases</i>, <i>tried</i>, <i>errors</i>, and <i>failures</i>
+are the count values.
+<p>
+The function <tt>showPath</tt> shows a test case path.
+<pre>
+    showPath :: Path -> String
+</pre>
+The nodes in the path are reversed (so that the path reads from the
+root down to the test case), and the representations for the nodes are
+joined by '<tt>:</tt>' separators. The representation for
+<tt>(ListItem <i>n</i>)</tt> is <tt>(show n)</tt>. The
+representation for <tt>(Label <i>label</i>)</tt> is normally
+<i>label</i>. However, if <i>label</i> contains a colon or if
+<tt>(show <i>label</i>)</tt> is different from <i>label</i> surrounded
+by quotation marks--that is, if any ambiguity could exist--then
+<tt>(Label <i>label</i>)</tt> is represented as <tt>(show
+<i>label</i>)</tt>.
+<p>
+HUnit includes two reporting schemes for the text-based test
+controller. You may define others if you wish.
+<pre>
+    putTextToHandle :: Handle -> Bool -> PutText Int
+</pre>
+<tt>putTextToHandle</tt> writes error and failure reports, plus a
+report of the final counts, to the given handle. Each of these
+reports is terminated by a newline. In addition, if the given
+flag is <tt>True</tt>, it writes start reports to the handle as
+well. A start report, however, is not terminated by a
+newline. Before the next report is written, the start report is
+"erased" with an appropriate sequence of carriage return and space
+characters. Such overwriting realizes its intended effect on
+terminal devices.
+<pre>
+    putTextToShowS :: PutText ShowS
+</pre>
+<tt>putTextToShowS</tt> ignores start reports and simply accumulates
+error and failure reports, terminating them with newlines. The
+accumulated reports are returned (as the second element of the pair
+returned by <tt>runTestText</tt>) as a <tt>ShowS</tt> function (that
+is, one with type <tt>(String&nbsp;->&nbsp;String)</tt>) whose first
+argument is a string to be appended to the accumulated report lines.
+<p>
+HUnit provides a shorthand for the most common use of the text-based
+test controller.
+<pre>
+    runTestTT :: Test -> IO Counts
+</pre>
+<tt>runTestTT</tt> invokes <tt>runTestText</tt>, specifying
+<tt>(putTextToHandle stderr True)</tt> for the reporting scheme, and
+returns the final counts from the test execution.
+
+<h2><a name="ConstituentFiles">Constituent Files</a></h2>
+
+HUnit 1.0 consists of the following files.
+<dl>
+
+<dt> doc/Guide.html
+<dd>
+This document.
+<dt> examples/Example.hs
+<dd>
+Haskell module that includes the examples given in the <a
+href="#GettingStarted">Getting Started</a> section. Run this
+program to make sure you understand how to use HUnit.
+<dt> Test/HUnit.lhs
+<dd>
+Haskell module that you import to use HUnit.
+<dt> Test/HUnit/Base.lhs
+<dd>
+Haskell module that defines HUnit's basic facilities.
+<dt> Test/HUnit/Lang.lhs
+<dd>
+Haskell module that defines how assertion failure is signaled and
+caught. By default, it is a copy of
+<tt>Test/HUnit/Lang98.lhs</tt>. Replace it by a copy of
+<tt>Test/HUnit/LangExtended.lhs</tt> for more robust exception behavior.
+<dt> Test/HUnit/Lang98.lhs
+<dd>
+Haskell module that defines generic assertion failure handling.&nbsp;
+It is compliant to Haskell 98 but catches only <tt>IO</tt> errors.
+<dt> Test/HUnit/LangExtended.lhs
+<dd>
+Haskell module that defines more robust assertion failure
+handling. It catches more (though unfortunately not all) kinds
+of exceptions. However, it works only with Hugs (Dec. 2001 or
+later) and GHC (5.00 and later).
+<dt> examples/test/HUnitTest98.lhs
+<dd>
+Haskell module that tests HUnit, assuming the generic assertion
+failure handling of <tt>HUnitLang98.lhs</tt>.
+<dt> examples/test/HUnitTestBase.lhs
+<dd>
+Haskell module that defines testing support and basic (Haskell 98
+compliant) tests of HUnit (using HUnit, of course!). Contains
+more extensive and advanced examples of testing with HUnit.
+<dt> examples/test/HUnitTestExtended.lhs
+<dd>
+Haskell module that tests HUnit, assuming the extended assertion
+failure handling of <tt>HUnitLangExc.lhs</tt>.
+<dt> Test/HUnit/Text.lhs
+<dd>
+Haskell module that defines HUnit's text-based test controller.
+<dt> LICENSE
+<dd>
+The license for use of HUnit.
+<dt> Test/HUnit/Terminal.lhs
+<dd>
+Haskell module that assists in checking the output of HUnit tests
+performed by the text-based test controller.
+<dt> examples/test/TerminalTest.lhs
+<dd>
+Haskell module that tests <tt>Test/HUnit/Terminal.lhs</tt> (using HUnit, of
+course!).
+</dl>
+
+<h2><a name="References">References</a></h2>
+
+<dl>
+
+<dt>
+<a name="DesignPatterns"></a>[1] Gamma, E., et al. Design Patterns:
+Elements of Reusable Object-Oriented Software, Addison-Wesley,
+Reading, MA, 1995.
+<dd>
+The classic book describing design patterns in an object-oriented
+context.
+
+<dt>
+<a href="http://www.junit.org">http://www.junit.org</a>
+<dd>
+Web page for JUnit, the tool after which HUnit is modeled.
+
+<dt>
+<a href="http://junit.sourceforge.net/doc/testinfected/testing.htm">
+http://junit.sourceforge.net/doc/testinfected/testing.htm</a>
+<dd>
+A good introduction to test-first development and the use of JUnit.
+
+<dt>
+<a href="http://junit.sourceforge.net/doc/cookstour/cookstour.htm">
+http://junit.sourceforge.net/doc/cookstour/cookstour.htm</a>
+<dd>
+A description of the internal structure of JUnit. Makes for an
+interesting comparison between JUnit and HUnit.
+
+</dl>
+
+<p>
+<hr>
+
+The HUnit software and this guide were written by Dean Herington
+(<a href="mailto:heringto@cs.unc.edu">heringto@cs.unc.edu</a>).
+
+<p>
+HUnit development is supported by
+<a href="http://sourceforge.net">
+<img src="http://sourceforge.net/sflogo.php?group_id=46796&amp;type=1"
+     width="88" height="31" border="0" alt="SourceForge.net Logo">
+</a>
+</body>
+</html>
diff --git a/examples/Example.hs b/examples/Example.hs
new file mode 100644
--- /dev/null
+++ b/examples/Example.hs
@@ -0,0 +1,37 @@
+-- Example.hs  --  Examples from HUnit user's guide
+
+module Main where
+
+import Test.HUnit
+
+
+foo :: Int -> (Int, Int)
+foo x = (1, x)
+
+partA :: Int -> IO (Int, Int)
+partA v = return (v+2, v+3)
+
+partB :: Int -> IO Bool
+partB v = return (v > 5)
+
+test1 :: Test
+test1 = TestCase (assertEqual "for (foo 3)," (1,2) (foo 3))
+
+test2 :: Test
+test2 = TestCase (do (x,y) <- partA 3
+                     assertEqual "for the first result of partA," 5 x
+                     b <- partB y
+                     assertBool ("(partB " ++ show y ++ ") failed") b)
+
+tests :: Test
+tests = TestList [TestLabel "test1" test1, TestLabel "test2" test2]
+
+tests' :: Test
+tests' = test [ "test1" ~: "(foo 3)" ~: (1,2) ~=? (foo 3),
+                "test2" ~: do (x, y) <- partA 3
+                              assertEqual "for the first result of partA," 5 x
+                              partB y @? "(partB " ++ show y ++ ") failed" ]
+
+main :: IO Counts
+main = do runTestTT tests
+          runTestTT tests'
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,27 @@
+# -----------------------------------------------------------------------------
+
+TOP = ../..
+include $(TOP)/mk/boilerplate.mk
+
+# -----------------------------------------------------------------------------
+
+ifeq "$(way)" ""
+SUBDIRS = test
+
+EXAMPLES    := $(wildcard *.hs)
+BINS        := $(addsuffix $(exeext),$(EXAMPLES:.hs=))
+CLEAN_FILES += $(BINS)
+
+HC           = $(GHC_INPLACE)
+MKDEPENDHS   = $(GHC_INPLACE)
+SRC_HC_OPTS += -Wall -package HUnit
+
+all:: $(BINS)
+
+$(BINS): %$(exeext): %.o
+	$(HC) -o $@ $(HC_OPTS) $(LD_OPTS) $<
+endif
+
+# -----------------------------------------------------------------------------
+
+include $(TOP)/mk/target.mk
diff --git a/examples/test/HUnitTest98.lhs b/examples/test/HUnitTest98.lhs
new file mode 100644
--- /dev/null
+++ b/examples/test/HUnitTest98.lhs
@@ -0,0 +1,9 @@
+HUnitTest98.lhs  --  test for HUnit, using Haskell language system "98"
+
+> module Main (main) where
+
+> import Test.HUnit
+> import HUnitTestBase
+
+> main :: IO Counts
+> main = runTestTT (test [baseTests])
diff --git a/examples/test/HUnitTestBase.lhs b/examples/test/HUnitTestBase.lhs
new file mode 100644
--- /dev/null
+++ b/examples/test/HUnitTestBase.lhs
@@ -0,0 +1,373 @@
+HUnitTestBase.lhs  --  test support and basic tests (Haskell 98 compliant)
+
+> module HUnitTestBase where
+
+> import Test.HUnit
+> import Test.HUnit.Terminal (terminalAppearance)
+> import System.IO (IOMode(..), openFile, hClose)
+
+
+> data Report = Start State
+>             | Error String State
+>             | UnspecifiedError State
+>             | Failure String State
+>   deriving (Show, Read)
+
+> instance Eq Report where
+>   Start s1            == Start s2             =  s1 == s2
+>   Error m1 s1         == Error m2 s2          =  m1 == m2 && s1 == s2
+>   Error m1 s1         == UnspecifiedError s2  =  s1 == s2
+>   UnspecifiedError s1 == Error m2 s2          =  s1 == s2
+>   UnspecifiedError s1 == UnspecifiedError s2  =  s1 == s2
+>   Failure m1 s1       == Failure m2 s2        =  m1 == m2 && s1 == s2
+>   _                   == _                    =  False
+
+
+> expectReports :: [Report] -> Counts -> Test -> Test
+> expectReports reports counts test = TestCase $ do
+>   (counts', reports') <- performTest (\  ss us -> return (Start     ss : us))
+>                                      (\m ss us -> return (Error   m ss : us))
+>                                      (\m ss us -> return (Failure m ss : us))
+>                                      [] test
+>   assertEqual "for the reports from a test," reports (reverse reports')
+>   assertEqual "for the counts from a test," counts counts'
+
+
+> simpleStart = Start (State [] (Counts 1 0 0 0))
+
+> expectSuccess :: Test -> Test
+> expectSuccess = expectReports [simpleStart] (Counts 1 1 0 0)
+
+> expectProblem :: (String -> State -> Report) -> Int -> String -> Test -> Test
+> expectProblem kind err msg =
+>   expectReports [simpleStart, kind msg (State [] counts)] counts
+>  where counts = Counts 1 1 err (1-err)
+
+> expectError, expectFailure :: String -> Test -> Test
+> expectError   = expectProblem Error   1
+> expectFailure = expectProblem Failure 0
+
+> expectUnspecifiedError :: Test -> Test
+> expectUnspecifiedError = expectProblem (\ msg st -> UnspecifiedError st) 1 undefined
+
+
+> data Expect = Succ | Err String | UErr | Fail String
+
+> expect :: Expect -> Test -> Test
+> expect Succ     test = expectSuccess test
+> expect (Err m)  test = expectError m test
+> expect UErr     test = expectUnspecifiedError test
+> expect (Fail m) test = expectFailure m test
+
+
+
+> baseTests = test [ assertTests,
+>                    testCaseCountTests,
+>                    testCasePathsTests,
+>                    reportTests,
+>                    textTests,
+>                    showPathTests,
+>                    showCountsTests,
+>                    assertableTests,
+>                    predicableTests,
+>                    compareTests,
+>                    extendedTestTests ]
+
+
+> ok = test (assert ())
+> bad m = test (assertFailure m)
+
+
+> assertTests = test [
+
+>   "null" ~: expectSuccess ok,
+
+>   "userError" ~:
+>     expectError "error" (TestCase (ioError (userError "error"))),
+
+>   "IO error (file missing)" ~:
+>     expectUnspecifiedError
+>       (test (do openFile "3g9djs" ReadMode; return ())),
+
+   "error" ~:
+     expectError "error" (TestCase (error "error")),
+
+   "tail []" ~:
+     expectUnspecifiedError (TestCase (tail [] `seq` return ())),
+
+    -- GHC doesn't currently catch arithmetic exceptions.
+   "div by 0" ~:
+     expectUnspecifiedError (TestCase ((3 `div` 0) `seq` return ())),
+
+>   "assertFailure" ~:
+>     let msg = "simple assertFailure"
+>     in expectFailure msg (test (assertFailure msg)),
+
+>   "assertString null" ~: expectSuccess (TestCase (assertString "")),
+
+>   "assertString nonnull" ~:
+>     let msg = "assertString nonnull"
+>     in expectFailure msg (TestCase (assertString msg)),
+
+>   let exp v non =
+>         show v ++ " with " ++ non ++ "null message" ~:
+>           expect (if v then Succ else Fail non) $ test $ assertBool non v
+>   in "assertBool" ~: [ exp v non | v <- [True, False], non <- ["non", ""] ],
+
+>   let msg = "assertBool True"
+>   in msg ~: expectSuccess (test (assertBool msg True)),
+
+>   let msg = "assertBool False"
+>   in msg ~: expectFailure msg (test (assertBool msg False)),
+
+>   "assertEqual equal" ~:
+>     expectSuccess (test (assertEqual "" 3 3)),
+
+>   "assertEqual unequal no msg" ~:
+>     expectFailure "expected: 3\n but got: 4"
+>       (test (assertEqual "" 3 4)),
+
+>   "assertEqual unequal with msg" ~:
+>     expectFailure "for x,\nexpected: 3\n but got: 4"
+>       (test (assertEqual "for x," 3 4))
+
+>  ]
+
+
+> emptyTest0 = TestList []
+> emptyTest1 = TestLabel "empty" emptyTest0
+> emptyTest2 = TestList [ emptyTest0, emptyTest1, emptyTest0 ]
+> emptyTests = [emptyTest0, emptyTest1, emptyTest2]
+
+> testCountEmpty test = TestCase (assertEqual "" 0 (testCaseCount test))
+
+> suite0 = (0, ok)
+> suite1 = (1, TestList [])
+> suite2 = (2, TestLabel "3" ok)
+> suite3 = (3, suite)
+
+> suite =
+>   TestLabel "0"
+>     (TestList [ TestLabel "1" (bad "1"),
+>                 TestLabel "2" (TestList [ TestLabel "2.1" ok,
+>                                           ok,
+>                                           TestLabel "2.3" (bad "2") ]),
+>                 TestLabel "3" (TestLabel "4" (TestLabel "5" (bad "3"))),
+>                 TestList [ TestList [ TestLabel "6" (bad "4") ] ] ])
+
+> suiteCount = (6 :: Int)
+
+> suitePaths = [
+>   [Label "0", ListItem 0, Label "1"],
+>   [Label "0", ListItem 1, Label "2", ListItem 0, Label "2.1"],
+>   [Label "0", ListItem 1, Label "2", ListItem 1],
+>   [Label "0", ListItem 1, Label "2", ListItem 2, Label "2.3"],
+>   [Label "0", ListItem 2, Label "3", Label "4", Label "5"],
+>   [Label "0", ListItem 3, ListItem 0, ListItem 0, Label "6"]]
+
+> suiteReports = [ Start       (State (p 0) (Counts 6 0 0 0)),
+>                  Failure "1" (State (p 0) (Counts 6 1 0 1)),
+>                  Start       (State (p 1) (Counts 6 1 0 1)),
+>                  Start       (State (p 2) (Counts 6 2 0 1)),
+>                  Start       (State (p 3) (Counts 6 3 0 1)),
+>                  Failure "2" (State (p 3) (Counts 6 4 0 2)),
+>                  Start       (State (p 4) (Counts 6 4 0 2)),
+>                  Failure "3" (State (p 4) (Counts 6 5 0 3)),
+>                  Start       (State (p 5) (Counts 6 5 0 3)),
+>                  Failure "4" (State (p 5) (Counts 6 6 0 4))]
+>  where p n = reverse (suitePaths !! n)
+
+> suiteCounts = Counts 6 6 0 4
+
+> suiteOutput = "### Failure in: 0:0:1\n\
+>               \1\n\
+>               \### Failure in: 0:1:2:2:2.3\n\
+>               \2\n\
+>               \### Failure in: 0:2:3:4:5\n\
+>               \3\n\
+>               \### Failure in: 0:3:0:0:6\n\
+>               \4\n\
+>               \Cases: 6  Tried: 6  Errors: 0  Failures: 4\n"
+
+
+> suites = [suite0, suite1, suite2, suite3]
+
+
+> testCount (num, test) count =
+>   "testCaseCount suite" ++ show num ~:
+>     TestCase $ assertEqual "for test count," count (testCaseCount test)
+
+> testCaseCountTests = TestList [
+
+>   "testCaseCount empty" ~: test (map testCountEmpty emptyTests),
+
+>   testCount suite0 1,
+>   testCount suite1 0,
+>   testCount suite2 1,
+>   testCount suite3 suiteCount
+
+>  ]
+
+
+> testPaths (num, test) paths =
+>   "testCasePaths suite" ++ show num ~:
+>     TestCase $ assertEqual "for test paths,"
+>                             (map reverse paths) (testCasePaths test)
+
+> testPathsEmpty test = TestCase $ assertEqual "" [] (testCasePaths test)
+
+> testCasePathsTests = TestList [
+
+>   "testCasePaths empty" ~: test (map testPathsEmpty emptyTests),
+
+>   testPaths suite0 [[]],
+>   testPaths suite1 [],
+>   testPaths suite2 [[Label "3"]],
+>   testPaths suite3 suitePaths
+
+>  ]
+
+
+> reportTests = "reports" ~: expectReports suiteReports suiteCounts suite
+
+
+> expectText counts text test = TestCase $ do
+>   (counts', text') <- runTestText putTextToShowS test
+>   assertEqual "for the final counts," counts counts'
+>   assertEqual "for the failure text output," text (text' "")
+
+
+> textTests = test [
+
+>   "lone error" ~:
+>     expectText (Counts 1 1 1 0)
+>         "### Error:\nxyz\nCases: 1  Tried: 1  Errors: 1  Failures: 0\n"
+>         (test (do ioError (userError "xyz"); return ())),
+
+>   "lone failure" ~:
+>     expectText (Counts 1 1 0 1)
+>         "### Failure:\nxyz\nCases: 1  Tried: 1  Errors: 0  Failures: 1\n"
+>         (test (assert "xyz")),
+
+>   "putTextToShowS" ~:
+>     expectText suiteCounts suiteOutput suite,
+
+>   "putTextToHandle (file)" ~:
+>     let filename = "HUnitTest.tmp"
+>         trim = unlines . map (reverse . dropWhile (== ' ') . reverse) . lines
+>     in map test
+>       [ "show progress = " ++ show flag ~: do
+>           handle <- openFile filename WriteMode
+>           (counts, _) <- runTestText (putTextToHandle handle flag) suite
+>           hClose handle
+>           assertEqual "for the final counts," suiteCounts counts
+>           text <- readFile filename
+>           let text' = if flag then trim (terminalAppearance text) else text
+>           assertEqual "for the failure text output," suiteOutput text'
+>       | flag <- [False, True] ]
+
+>  ]
+
+
+> showPathTests = "showPath" ~: [
+
+>   "empty"  ~: showPath [] ~?= "",
+>   ":"      ~: showPath [Label ":", Label "::"] ~?= "\"::\":\":\"",
+>   "\"\\\n" ~: showPath [Label "\"\\n\n\""] ~?= "\"\\\"\\\\n\\n\\\"\"",
+>   "misc"   ~: showPath [Label "b", ListItem 2, ListItem 3, Label "foo"] ~?=
+>                        "foo:3:2:b"
+
+>  ]
+
+
+> showCountsTests = "showCounts" ~: showCounts (Counts 4 3 2 1) ~?=
+>                             "Cases: 4  Tried: 3  Errors: 2  Failures: 1"
+
+
+
+> lift :: a -> IO a
+> lift a = return a
+
+
+> assertableTests =
+>   let assertables x = [
+>         (       "", assert             x  , test             (lift x))  ,
+>         (    "IO ", assert       (lift x) , test       (lift (lift x))) ,
+>         ( "IO IO ", assert (lift (lift x)), test (lift (lift (lift x))))]
+>       assertabled l e x =
+>         test [ test [ "assert" ~: pre ++ l          ~: expect e $ test $ a,
+>                       "test"   ~: pre ++ "IO " ++ l ~: expect e $ t ]
+>                | (pre, a, t) <- assertables x ]
+>   in "assertable" ~: [
+>     assertabled "()"    Succ       (),
+>     assertabled "True"  Succ       True,
+>     assertabled "False" (Fail "")  False,
+>     assertabled "\"\""  Succ       "",
+>     assertabled "\"x\"" (Fail "x") "x"
+>    ]
+
+
+> predicableTests =
+>   let predicables x m = [
+>         (       "", assertionPredicate      x  ,     x  @? m,     x  ~? m ),
+>         (    "IO ", assertionPredicate   (l x) ,   l x  @? m,   l x  ~? m ),
+>         ( "IO IO ", assertionPredicate (l(l x)), l(l x) @? m, l(l x) ~? m )]
+>       l x = lift x
+>       predicabled l e m x =
+>         test [ test [ "pred" ~: pre ++ l ~: m ~: expect e $ test $ tst p,
+>                       "(@?)" ~: pre ++ l ~: m ~: expect e $ test $ a,
+>                       "(~?)" ~: pre ++ l ~: m ~: expect e $ t ]
+>                                    | (pre, p, a, t) <- predicables x m ]
+>        where tst p = p >>= assertBool m
+>   in "predicable" ~: [
+>     predicabled "True"  Succ           "error" True,
+>     predicabled "False" (Fail "error") "error" False,
+>     predicabled "True"  Succ           ""      True,
+>     predicabled "False" (Fail ""     ) ""      False
+>    ]
+
+
+> compareTests = test [
+
+>   let succ = const Succ
+>       compare f exp act = test [ "(@=?)" ~: expect e $ test (exp @=? act),
+>                                  "(@?=)" ~: expect e $ test (act @?= exp),
+>                                  "(~=?)" ~: expect e $       exp ~=? act,
+>                                  "(~?=)" ~: expect e $       act ~?= exp ]
+>        where e = f $ "expected: " ++ show exp ++ "\n but got: " ++ show act
+>   in test [
+>     compare succ 1 1,
+>     compare Fail 1 2,
+>     compare succ (1,'b',3.0) (1,'b',3.0),
+>     compare Fail (1,'b',3.0) (1,'b',3.1)
+>    ]
+
+>  ]
+
+
+> expectList1 :: Int -> Test -> Test
+> expectList1 c =
+>   expectReports
+>     [ Start (State [ListItem n] (Counts c n 0 0)) | n <- [0..c-1] ]
+>                                 (Counts c c 0 0)
+
+> expectList2 :: [Int] -> Test -> Test
+> expectList2 cs test =
+>   expectReports
+>     [ Start (State [ListItem j, ListItem i] (Counts c n 0 0))
+>         | ((i,j),n) <- zip coords [0..] ]
+>                                             (Counts c c 0 0)
+>                    test
+>  where coords = [ (i,j) | i <- [0 .. length cs - 1], j <- [0 .. cs!!i - 1] ]
+>        c = testCaseCount test
+
+
+> extendedTestTests = test [
+
+>   "test idempotent" ~: expect Succ $ test $ test $ test $ ok,
+
+>   "test list 1" ~: expectList1 3 $ test [assert (), assert "", assert True],
+
+>   "test list 2" ~: expectList2 [0, 1, 2] $ test [[], [ok], [ok, ok]]
+
+>  ]
diff --git a/examples/test/HUnitTestExtended.lhs b/examples/test/HUnitTestExtended.lhs
new file mode 100644
--- /dev/null
+++ b/examples/test/HUnitTestExtended.lhs
@@ -0,0 +1,38 @@
+HUnitTestExc.lhs  --  test for HUnit, using Haskell language system "Exc"
+
+> module Main (main) where
+
+> import Test.HUnit
+> import HUnitTestBase
+
+ import qualified Control.Exception (assert)
+
+ assertionMessage = "HUnitTestExc.lhs:13: Assertion failed\n"
+ assertion = Control.Exception.assert False (return ())
+
+
+> main :: IO Counts
+> main = runTestTT (test [baseTests, excTests])
+
+> excTests :: Test
+> excTests = test [
+
+    -- Hugs and GHC don't currently catch arithmetic exceptions.
+   "div by 0" ~:
+     expectUnspecifiedError (TestCase ((3 `div` 0) `seq` return ())),
+
+    -- GHC doesn't currently catch array-related exceptions.
+   "array ref out of bounds" ~:
+     expectUnspecifiedError (TestCase (... `seq` return ())),
+
+>   "error" ~:
+>     expectError "error" (TestCase (error "error")),
+
+>   "tail []" ~:
+>     expectUnspecifiedError (TestCase (tail [] `seq` return ()))
+
+   -- Hugs doesn't provide `assert`.
+   "assert" ~:
+     expectError assertionMessage (TestCase assertion)
+
+>  ]
diff --git a/examples/test/Makefile b/examples/test/Makefile
new file mode 100644
--- /dev/null
+++ b/examples/test/Makefile
@@ -0,0 +1,29 @@
+# -----------------------------------------------------------------------------
+
+TOP = ../../..
+include $(TOP)/mk/boilerplate.mk
+
+# -----------------------------------------------------------------------------
+
+EXAMPLES    := $(filter-out HUnitTestBase.lhs,$(wildcard *.lhs))
+BINS        := $(addsuffix $(exeext),$(EXAMPLES:.lhs=))
+CLEAN_FILES += $(BINS)
+
+HC           = $(GHC_INPLACE)
+MKDEPENDHS   = $(GHC_INPLACE)
+SRC_HC_OPTS += -Wall -package HUnit
+
+all:: $(BINS)
+
+USES_HUNITTESTBASE := $(EXAMPLES:.lhs=)
+
+.PRECIOUS: HUnitTestBase.o
+$(addsuffix .o,$(USES_HUNITTESTBASE)): HUnitTestBase.hi
+$(addsuffix $(exeext),$(USES_HUNITTESTBASE)): HUnitTestBase.o
+
+$(BINS): %$(exeext): %.o
+	$(HC) -o $@ $(HC_OPTS) $(LD_OPTS) $< $(patsubst %,HUnitTestBase.o,$(filter $(<:.o=),$(USES_HUNITTESTBASE)))
+
+# -----------------------------------------------------------------------------
+
+include $(TOP)/mk/target.mk
diff --git a/examples/test/TerminalTest.lhs b/examples/test/TerminalTest.lhs
new file mode 100644
--- /dev/null
+++ b/examples/test/TerminalTest.lhs
@@ -0,0 +1,24 @@
+TerminalTest.lhs
+
+> import Test.HUnit.Terminal
+> import Test.HUnit
+
+> main :: IO Counts
+> main = runTestTT tests
+
+> try :: String -> String -> String -> Test
+> try lab inp exp' = lab ~: terminalAppearance inp ~?= exp'
+
+> tests :: Test
+> tests = test [
+>   try "empty" "" "",
+>   try "end in \\n" "abc\ndef\n" "abc\ndef\n",
+>   try "not end in \\n" "abc\ndef" "abc\ndef",
+>   try "return 1" "abc\ndefgh\rxyz" "abc\nxyzgh",
+>   try "return 2" "\nabcdefgh\rijklm\rxy\n" "\nxyklmfgh\n",
+>   try "return 3" "\r\rabc\r\rdef\r\r\r\nghi\r\r\n" "def\nghi\n",
+>   try "back 1" "abc\bdef\b\bgh\b" "abdgh",
+>   try "back 2" "abc\b\b\bdef\b\bxy\b\b\n" "dxy\n"
+>   -- \b at beginning of line
+>   -- nonprinting char
+>  ]
diff --git a/prologue.txt b/prologue.txt
new file mode 100644
--- /dev/null
+++ b/prologue.txt
@@ -0,0 +1,2 @@
+HUnit is a unit testing framework for Haskell, inspired by the JUnit
+tool for Java, see: <http://www.junit.org>.
