diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,4 +4,4 @@
 [![hackage release](https://img.shields.io/hackage/v/hsemail.svg?label=hackage)](http://hackage.haskell.org/package/hsemail)
 [![stackage LTS package](http://stackage.org/package/hsemail/badge/lts)](http://stackage.org/lts/package/hsemail)
 [![stackage Nightly package](http://stackage.org/package/hsemail/badge/nightly)](http://stackage.org/nightly/package/hsemail)
-[![travis build status](https://img.shields.io/travis/peti/hsemail/master.svg?label=travis+build)](https://travis-ci.org/peti/hsemail)
+[![build status](https://github.com/peti/hsemail/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/peti/hsemail/actions/workflows/haskell-ci.yml)
diff --git a/example/message-test.hs b/example/message-test.hs
new file mode 100644
--- /dev/null
+++ b/example/message-test.hs
@@ -0,0 +1,21 @@
+module Main (main) where
+
+import Text.Parsec ( parse )
+import Text.Parsec.Rfc2822
+
+-- Read an Internet message from standard input, parse it,
+-- and return the result.
+
+main :: IO ()
+main = do
+  input <- getContents
+  print $ parse message "<stdin>" (fixEol input)
+  return ()
+
+-- Make sure all lines are terminated by CRLF.
+
+fixEol :: String -> String
+fixEol ('\r':'\n':xs)   = '\r' : '\n' : fixEol xs
+fixEol ('\n':xs)        = '\r' : '\n' : fixEol xs
+fixEol (x:xs)           = x : fixEol xs
+fixEol []               = []
diff --git a/hsemail.cabal b/hsemail.cabal
--- a/hsemail.cabal
+++ b/hsemail.cabal
@@ -1,38 +1,89 @@
 name:               hsemail
-version:            2.2.1
+version:            2.2.2
 synopsis:           Parsec parsers for the Internet Message format (e-mail)
-description:        Parsec parsers for the Internet Message format defined in RFC2822.
+description:
+  Parsec parsers for the Internet Message format defined in RFC2822.
+
 license:            BSD3
 license-file:       LICENSE
-author:             Peter Simons,
-                    Ali Abrar,
-                    Gero Kriependorf,
-                    Marty Pauley
+author:
+  Peter Simons,
+  Ali Abrar,
+  Gero Kriependorf,
+  Marty Pauley
+
 maintainer:         Peter Simons <simons@cryp.to>
 stability:          stable
-tested-with:        GHC == 7.10.3 || == 8.0.2 || == 8.2.2 || == 8.4.4 || == 8.6.5 || == 8.8.4 || == 8.10.2
+tested-with:
+  GHC ==7.10.3
+   || ==8.0.2
+   || ==8.2.2
+   || ==8.4.4
+   || ==8.6.5
+   || ==8.8.4
+   || ==8.10.7
+   || ==9.0.2
+   || ==9.2.8
+   || ==9.4.8
+   || ==9.6.4
+   || ==9.8.1
+
 category:           Parsing
 homepage:           https://github.com/peti/hsemail#readme
 bug-reports:        https://github.com/peti/hsemail/issues
 build-type:         Simple
-extra-source-files: ChangeLog.md
-                    README.md
-cabal-version:      >= 1.10
+extra-source-files:
+  ChangeLog.md
+  README.md
 
+cabal-version:      >=1.10
+
 source-repository head
   type:     git
   location: https://github.com/peti/hsemail
 
+flag install-examples
+  description: Build and install example programs.
+  default:     False
+
 library
-  exposed-modules:  Text.Parsec.Rfc2234
-                    Text.Parsec.Rfc2822
+  exposed-modules:
+    Text.Parsec.Rfc2234
+    Text.Parsec.Rfc2822
+
   hs-source-dirs:   src
-  build-depends:    base > 4.8 && < 5, parsec == 3.1.*, time, time-compat == 1.9.*
+  build-depends:
+      base         >=4.8.0 && <5
+    , parsec       >=3.1   && <3.2
+    , time
+    , time-compat  >=1.9   && <1.10
+
   default-language: Haskell2010
 
 test-suite test-hsemail
   type:             exitcode-stdio-1.0
   main-is:          spec.hs
   hs-source-dirs:   test
-  build-depends:    base, hsemail, hspec, parsec, time
+  build-depends:
+      base
+    , hsemail
+    , hspec
+    , parsec
+    , time
+
   default-language: Haskell2010
+
+executable message-test
+  main-is:          message-test.hs
+  hs-source-dirs:   example
+  default-language: Haskell2010
+
+  if flag(install-examples)
+    buildable:     True
+    build-depends:
+        base
+      , hsemail
+      , parsec
+
+  else
+    buildable: False
