diff --git a/COPYING b/COPYING
new file mode 100644
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,26 @@
+Copyright (c) 2012, 2013 Joachim Fasting
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+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
+OWNER 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.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,11 @@
+# acme-omitted: purely functional omitted content for Haskell
+
+Standard Haskell lacks the ability to express the notion of "omitted content",
+making it impossible to distinguish the truly "undefined" and the merely "omitted".
+
+acme-omitted provides
+
+- a universal definition of "omitted"; and
+- functions to observe the difference between omitted and undefined.
+
+The library is standards-compliant, type-safe, and user-friendly.
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/acme-omitted.cabal b/acme-omitted.cabal
new file mode 100644
--- /dev/null
+++ b/acme-omitted.cabal
@@ -0,0 +1,57 @@
+Name:                acme-omitted
+Version:             1.1.0.0
+Synopsis:            Purely functional omitted content for Haskell
+Category:            Acme
+Stability:           stable
+Description:
+    Standard Haskell lacks the ability to express the notion of \"omitted content\",
+    making it impossible to distinguish the truly \"undefined\" and the
+    merely \"omitted\".
+    .
+    acme-omitted implements a universal definition of \"omitted\" and provides
+    means of observing whether a definition has been omitted or if it is truly
+    undefined.
+    .
+    The library is standards-compliant, type-safe, and user-friendly.
+
+License:             BSD3
+License-file:        COPYING
+
+Author:              Joachim Fasting
+Maintainer:          joachim.fasting@gmail.com
+Copyright:           (c) 2013 Joachim Fasting
+Homepage:            https://github.com/joachifm/acme-omitted#readme
+
+Extra-source-files:
+    README.markdown
+
+Build-type:          Simple
+Cabal-version:       >= 1.10
+
+Source-repository head
+  Type: git
+  location: git@github.com:joachifm/acme-omitted.git
+
+Library
+  Default-language: Haskell2010
+
+  Exposed-modules:     Acme.Omitted
+
+  Build-depends:
+    base >= 3.0.3 && < 5
+
+  Hs-Source-Dirs: src
+
+  ghc-options:
+    -Wall
+
+Test-Suite specs
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  Hs-Source-Dirs: src tests
+
+  Build-depends:
+      base >= 3.0.3
+    , hspec
+    , hspec-discover
diff --git a/src/Acme/Omitted.hs b/src/Acme/Omitted.hs
new file mode 100644
--- /dev/null
+++ b/src/Acme/Omitted.hs
@@ -0,0 +1,117 @@
+{- |
+Module      : Acme.Omitted
+Description : A universal definition of omitted content
+Copyright   : (c) 2013 Joachim Fasting
+License     : BSD3
+
+Maintainer  : joachim.fasting@gmail.com
+Stability   : stable
+Portability : portable
+
+A universal definition of \"omitted content\" and methods
+for observing whether a definition is merely \"omitted\" or
+truly \"undefined\".
+-}
+
+module Acme.Omitted
+  (
+    -- * A universal definition of \"omitted content\"
+    --
+    -- $omitted
+    omitted
+  , (...)
+
+    -- * Observing the difference between \"omitted\" and \"undefined\"
+    --
+    -- $observing
+  , isOmitted
+  , isUndefined
+  ) where
+
+import qualified Control.Exception as E
+
+------------------------------------------------------------------------
+-- $omitted
+--
+-- The difference between \"omitted\" and \"undefined\" is that the
+-- programmer may choose to omit something but he cannot define the
+-- undefinable.
+-- The former is contingent on the whims of the programmer, the latter
+-- a fundamental truth.
+--
+-- Operationally, there is no difference between undefined and omitted;
+-- attempting to evaluate either is treated as an error.
+--
+-- Ideally, programmers would only ever use 'undefined' for things that
+-- are truly undefined, e.g., division by zero, and use 'omitted' for
+-- definitions that have yet to be written or that are currently not needed.
+
+-- | Alternative syntax for 'omitted' that has been carefully
+-- optimised for programmer convenience and visual presentation
+-- (e.g., for use in printed documents).
+--
+-- Example usage:
+--
+--    > definition = (...)
+(...) :: a
+(...) = omitted
+
+-- | The universal omitted content operator.
+--
+-- This is sufficient to express _all_ types of omitted content
+omitted :: a
+omitted = error "omitted"
+
+------------------------------------------------------------------------
+-- $observing
+--
+-- The following definitions allow the user to discriminate undefined
+-- omitted values.
+-- Some caveats apply, however.
+--
+-- Though 'isUndefined' arguably could be a pure function (what is by
+-- definition undefinable shall always remain undefined), we feel it most
+-- appropriate to keep both 'isOmitted' and 'isUndefined' in 'IO', for
+-- reasons of symmetry and because the distinction between omitted and
+-- undefined is a 'GHC.Prim.RealWorld' concern (in the end, both denote the
+-- same value, i.e., bottom).
+--
+-- Another reason to keep 'isUndefined' in 'IO' is the regrettable state of
+-- modern Haskell, which has forced programmers to use 'undefined' for all
+-- sorts of purposes where 'omitted' should have been used instead.
+-- Thus it is unsound to assume that 'undefined' values will remain so, or
+-- indeed make any assumptions about it at all.
+--
+-- The confounding of \"undefined\" and \"omitted\" also means that,
+-- as it stands, 'isUndefined' will return bogus results for some uses of
+-- 'undefined'.
+-- A possible refinement is to provide an alternative to \"Prelude.undefined\"
+-- that could be assumed to only represent values that are \"truly undefined\".
+-- For now, 'isUndefined' is provided as a convenience, but users are adviced to
+-- not rely on its results.
+-- Users are, however, encouraged to file bugs against libraries making unsound
+-- use of 'undefined'.
+
+-- | Answer the age-old question \"was this definition omitted?\"
+--
+-- @
+-- isOmitted 0         = return False
+-- isOmitted undefined = return False
+-- isOmitted omitted   = return True
+-- @
+isOmitted :: a -> IO Bool
+isOmitted = isErrorCall "omitted"
+
+-- | ... or is it really 'undefined'?
+--
+-- @
+-- isUndefined 0         = return False
+-- isUndefined omitted   = return False
+-- isUndefined undefined = return True
+-- @
+isUndefined :: a -> IO Bool
+isUndefined = isErrorCall "Prelude.undefined"
+
+isErrorCall :: String -> a -> IO Bool
+isErrorCall s x = (E.evaluate x >> return False)
+                  `E.catch` (\(E.ErrorCall e) -> return $ e == s)
diff --git a/tests/Spec.hs b/tests/Spec.hs
new file mode 100644
--- /dev/null
+++ b/tests/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
