diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+.cabal-sandbox
+cabal.sandbox.config
+.stack-work
+idx/
+dist/
+log/
+doc/
+*.swp
+*.swo
+*.swn
+*.swm
+*.o
+*.hi
+*.dyn_hi
+*.dyn_o
+tests/test
+doc/*.html
+doc/*.css
+doc/*.js
+doc/*.png
+doc/*.gif
+mk/toplibs
+eg/minimal
+README.html
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,65 @@
+# .travis.yml file for test-framework-leancheck
+#
+# Copyright:   (c) 2017-2018 Rudy Matela
+# License:     3-Clause BSD  (see the file LICENSE)
+# Maintainer:  Rudy Matela <rudy@matela.com.br>
+
+language: c  # not really
+
+notifications:
+  email:
+    on_failure: change
+
+sudo: false
+
+cache:
+  directories:
+  - $HOME/.ghc
+  - $HOME/.cabal
+  - $HOME/.stack
+
+before_install:
+- export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
+- ghc --version
+- cabal --version
+- haddock --version
+- rm -f ~/.cabal/config && cabal update
+# Download and unpack the stack executable
+# "Once Travis whitelists the stack.dev files," simply include stack in the
+# addons section. -- https://docs.haskellstack.org/en/stable/travis_ci/
+- mkdir -p ~/.local/bin
+- export PATH=$HOME/.local/bin:$PATH
+- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
+- stack config set system-ghc --global true
+- stack --version
+- cabal install --only-dependencies
+
+script:
+- make && make test && make haddock
+- make test-sdist
+- cabal test --ghc-option=-O0
+- stack $STACKR --no-terminal --skip-ghc-check test --ghc-options=-O0
+
+matrix:
+  allow_failures:
+  - ghc: 'head'
+  include:
+  - ghc: 'head'
+    env:                   GHCVER=head         CABALVER=head
+    addons: {apt: {packages: [ghc-head,   cabal-install-head], sources: hvr-ghc}}
+  - ghc: '8.4'
+    env:                   GHCVER=8.4.3        CABALVER=2.2
+    addons: {apt: {packages: [ghc-8.4.3,  cabal-install-2.2],  sources: hvr-ghc}}
+  - ghc: '8.2'
+    env:                   GHCVER=8.2.2        CABALVER=2.0    STACKR=--resolver=lts-11
+    addons: {apt: {packages: [ghc-8.2.2,  cabal-install-2.0],  sources: hvr-ghc}}
+  - ghc: '8.0'
+    env:                   GHCVER=8.0.2        CABALVER=1.24   STACKR=--resolver=lts-11
+    addons: {apt: {packages: [ghc-8.0.2,  cabal-install-1.24], sources: hvr-ghc}}
+  - ghc: '7.10'
+    env:                   GHCVER=7.10.3       CABALVER=1.22
+    addons: {apt: {packages: [ghc-7.10.3, cabal-install-1.22], sources: hvr-ghc}}
+    script:
+    - make && make test && make haddock
+    - make test-sdist
+    - cabal test --ghc-option=-O0
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2018, Rudy Matela
+
+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.
+
+    * Neither the name of Rudy Matela nor the names of other
+      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
+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/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,80 @@
+# Makefile for test-framework-leancheck
+#
+# Copyright:   (c) 2015-2018 Rudy Matela
+# License:     3-Clause BSD  (see the file LICENSE)
+# Maintainer:  Rudy Matela <rudy@matela.com.br>
+TESTS = \
+  tests/test
+EGS = \
+  eg/minimal
+BENCHS =
+GHCIMPORTDIRS = src
+GHCFLAGS = -O2 $(shell grep -q "Arch Linux" /etc/lsb-release && echo -dynamic)
+HADDOCKFLAGS = --no-print-missing-docs \
+  $(shell grep -q "Arch Linux" /etc/lsb-release && echo --optghc=-dynamic)
+
+all: mk/toplibs
+
+all-all: mk/All.o
+
+test: $(patsubst %,%.test,$(TESTS))
+
+%.test: %
+	./$<
+
+clean: clean-hi-o clean-haddock
+	rm -f $(TESTS) $(BENCHS) $(EGS) mk/toplibs
+
+ghci: mk/All.ghci
+
+install:
+	@echo "use \`cabal install' instead"
+
+test-sdist:
+	./tests/test-sdist
+
+test-via-cabal:
+	cabal test
+
+test-via-stack:
+	stack test
+
+test-via-everything: test test-via-cabal test-via-stack
+
+legacy-test: # needs ghc-8.0 .. ghc-7.8 installed as such
+	make clean  &&  make test GHC=ghc-8.2  GHCFLAGS="-Werror -dynamic"
+	make clean  &&  make test GHC=ghc-8.0  GHCFLAGS="-Werror -dynamic"
+	make clean  &&  make test GHC=ghc-7.10 GHCFLAGS="-Werror -dynamic"
+	make clean  &&  make test GHC=ghc-7.8  GHCFLAGS="-Werror -dynamic"
+	make clean  &&  make test
+
+legacy-test-via-cabal: # needs similarly named cabal wrappers
+	cabal clean  &&  cabal-ghc-8.2  configure  &&  cabal-ghc-8.2  test
+	cabal clean  &&  cabal-ghc-8.0  configure  &&  cabal-ghc-8.0  test
+	cabal clean  &&  cabal-ghc-7.10 configure  &&  cabal-ghc-7.10 test
+	cabal clean  &&  cabal-ghc-7.8  configure  &&  cabal-ghc-7.8  test
+	cabal clean  &&  cabal test
+
+prepare:
+	cabal update  &&  cabal install --only-dependencies
+
+prepare-legacy-test:
+	cabal-ghc-8.2  update  &&  cabal-ghc-8.2  install --only-dependencies
+	cabal-ghc-8.0  update  &&  cabal-ghc-8.0  install --only-dependencies
+	cabal-ghc-7.10 update  &&  cabal-ghc-7.10 install --only-dependencies
+	cabal-ghc-7.8  update  &&  cabal-ghc-7.8  install --only-dependencies
+
+hlint:
+	hlint \
+	  --ignore "Use import/export shortcut" \
+	  --ignore "Redundant bracket" \
+	  .
+
+# NOTE: (very hacky!) the following target allows parallel compilation (-jN) of
+# eg and tests programs so long as they don't share dependencies _not_ stored
+# in src/ and tests/.  Runnable binaries should depend on mk/toplibs instead of
+# actual Haskell source files
+mk/toplibs: mk/Toplibs.o
+	touch mk/toplibs
+
+include mk/haskell.mk
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,111 @@
+test-framework-leancheck: LeanCheck support for test-framework
+==============================================================
+
+[![test-framework-leancheck's Build Status][build-status]][build-log]
+[![test-framework-leancheck on Hackage][hackage-version]][test-framework-leancheck-on-hackage]
+[![test-framework-leancheck on Stackage LTS][stackage-lts-badge]][test-framework-leancheck-on-stackage-lts]
+[![test-framework-leancheck on Stackage Nightly][stackage-nightly-badge]][test-framework-leancheck-on-stackage-nightly]
+
+[LeanCheck] support for the [test-framework] test framework.
+
+
+Installing
+----------
+
+    $ cabal install test-framework-leancheck
+
+
+Example
+-------
+
+Here's how your `test.hs` might look like:
+
+```haskell
+import Test.Framework
+import Test.Framework.Providers.LeanCheck as LC
+import Data.List
+
+main :: IO ()
+main = defaultMain tests
+
+tests :: [Test]
+tests =
+  [ LC.testProperty "sort . sort == sort"
+      $ \xs -> sort (sort xs :: [Int]) == sort xs
+  , LC.testProperty "sort == id" -- not really, should fail
+      $ \xs -> sort (xs :: [Int]) == xs
+  ]
+```
+
+And here is the output for the above program:
+
+```
+$ ./eg/test
+sort . sort == sort: [OK, passed 100 tests.]
+sort == id: [Failed]
+*** Failed! Falsifiable (after 7 tests):
+[1,0]
+
+         Properties  Total
+ Passed  1           1
+ Failed  1           1
+ Total   2           2
+```
+
+
+Options
+-------
+
+Use `-a` or `--maximum-generated-tests` to configure
+the maximum number of tests for each property.
+
+```
+$ ./eg/test -a5
+sort . sort == sort: [OK, passed 5 tests.]
+sort == id: [OK, passed 5 tests.]
+
+         Properties  Total      
+ Passed  2           2          
+ Failed  0           0          
+ Total   2           2          
+```
+
+Since LeanCheck is enumerative,
+you may want to increate the default number of tests (100).
+Arbitrary rule of thumb:
+
+* between 200 to 500 on a developer machine;
+* between 1000 and 5000 on the CI.
+
+Your mileage may vary.
+
+
+Further reading
+---------------
+
+* [test-framework-leancheck's Haddock documentation];
+* [LeanCheck's Haddock documentation];
+* [test-framework's Haddock documentation];
+* [LeanCheck's README];
+* [test-framework's official example];
+* [Tutorial on property-based testing with LeanCheck].
+
+[test-framework-leancheck's Haddock documentation]: https://hackage.haskell.org/package/test-framework-leancheck/docs/Test-Framework-Providers-LeanCheck.html
+[LeanCheck's Haddock documentation]:      https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html
+[test-framework's Haddock documentation]: https://hackage.haskell.org/package/test-framework/docs/Test-Framework.html
+[LeanCheck's README]:                     https://github.com/rudymatela/leancheck#readme
+[test-framework's official example]: https://raw.githubusercontent.com/haskell/test-framework/master/example/Test/Framework/Example.lhs
+[tutorial on property-based testing with LeanCheck]: https://github.com/rudymatela/leancheck/blob/master/doc/tutorial.md
+
+[test-framework]: https://github.com/haskell/test-framework
+[LeanCheck]:      https://github.com/rudymatela/leancheck
+
+[build-status]: https://travis-ci.org/rudymatela/test-framework-leancheck.svg?branch=master
+[build-log]:    https://travis-ci.org/rudymatela/test-framework-leancheck
+[hackage-version]:                              https://img.shields.io/hackage/v/test-framework-leancheck.svg
+[test-framework-leancheck-on-hackage]:          https://hackage.haskell.org/package/test-framework-leancheck
+[stackage-lts-badge]:                           http://stackage.org/package/test-framework-leancheck/badge/lts
+[stackage-nightly-badge]:                       http://stackage.org/package/test-framework-leancheck/badge/nightly
+[test-framework-leancheck-on-stackage]:         http://stackage.org/package/test-framework-leancheck
+[test-framework-leancheck-on-stackage-lts]:     http://stackage.org/lts/package/test-framework-leancheck
+[test-framework-leancheck-on-stackage-nightly]: http://stackage.org/nightly/package/test-framework-leancheck
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/TODO.md b/TODO.md
new file mode 100644
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,7 @@
+TO DO list for test-framework-leancheck
+=======================================
+
+For now, the following should suffice:
+
+	$ alias lstodo='grep --color -nREi "TODO(:|\{)" *'
+	$ lstodo
diff --git a/eg/minimal.hs b/eg/minimal.hs
new file mode 100644
--- /dev/null
+++ b/eg/minimal.hs
@@ -0,0 +1,20 @@
+-- Copyright (c) 2018 Rudy Matela.
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+--
+-- Minimal example of using LeanCheck with test-framework.
+import Test.Framework
+import Test.Framework.Providers.LeanCheck as LC
+import Data.List
+
+main :: IO ()
+main = defaultMain tests
+
+tests :: [Test]
+tests =
+  [ LC.testProperty "sort . sort == sort"
+      $ \xs -> sort (sort xs :: [Int]) == sort xs
+  , LC.testProperty "sort == id" -- not really, should fail
+      $ \xs -> sort (xs :: [Int]) == xs
+  , LC.testProperty "head . sort == minimum h" -- not really, error
+      $ \xs -> head (sort xs :: [Int]) == minimum xs
+  ]
diff --git a/mk/All.hs b/mk/All.hs
new file mode 100644
--- /dev/null
+++ b/mk/All.hs
@@ -0,0 +1,6 @@
+module All
+  ( module Test.Framework.Providers.LeanCheck
+  )
+where
+
+import Test.Framework.Providers.LeanCheck
diff --git a/mk/Toplibs.hs b/mk/Toplibs.hs
new file mode 100644
--- /dev/null
+++ b/mk/Toplibs.hs
@@ -0,0 +1,4 @@
+-- Using ghc --make in this module triggers compilation of every library.
+module Toplibs () where
+
+import Test.Framework.Providers.LeanCheck ()
diff --git a/mk/depend.mk b/mk/depend.mk
new file mode 100644
--- /dev/null
+++ b/mk/depend.mk
@@ -0,0 +1,25 @@
+eg/minimal: \
+  eg/minimal.hs \
+  mk/toplibs
+eg/minimal.o: \
+  src/Test/Framework/Providers/LeanCheck.hs \
+  eg/minimal.hs
+mk/All.o: \
+  src/Test/Framework/Providers/LeanCheck.hs \
+  mk/All.hs
+mk/Toplibs.o: \
+  src/Test/Framework/Providers/LeanCheck.hs \
+  mk/Toplibs.hs
+Setup.o: \
+  Setup.hs
+Setup: \
+  Setup.hs \
+  mk/toplibs
+src/Test/Framework/Providers/LeanCheck.o: \
+  src/Test/Framework/Providers/LeanCheck.hs
+tests/test.o: \
+  tests/test.hs \
+  src/Test/Framework/Providers/LeanCheck.hs
+tests/test: \
+  tests/test.hs \
+  mk/toplibs
diff --git a/mk/ghcdeps b/mk/ghcdeps
new file mode 100644
--- /dev/null
+++ b/mk/ghcdeps
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# ghcdeps: generate Haskell make dependencies for compiling with GHC.
+#
+# Copyright (c) 2015-2018 Rudy Matela.
+# Distributed under the 3-Clause BSD licence.
+#
+# From a list of files provided on standard input,
+# generate flat make dependencies.
+#
+# Transitive relations are repeated.
+#
+# Usage:
+#   $ ghcdeps -isomedir:someother <<LIST
+#   program.hs
+#   Library.hs
+#   Path/To/Library.hs
+#   LIST
+#   program: ...
+#   Library.o: ...
+#   Path/To/Library.o: ...
+#
+# Or:
+#   $ find -name \*.hs -o -name \*.lhs | ghcdeps [GHCFLAGS]
+#   ...
+#
+# Note that when using find, you have to remember to exclude unecessary files,
+# e.g.:  dist, Setup.hs
+#
+# Yes, this is hacky.  But hey, it works.
+while read fn
+do
+	ghc "$@" -dep-suffix=. -dep-makefile=tmp.mk -M "$fn" ||
+	exit 1
+	deps="`cat tmp.mk |
+	       grep "hs$" |
+	       sort |
+	       sed -e "s/.*: //" |
+	       tac |
+	       tr '\n' ' ' |
+	       sed -e "s/ $//"`"
+	obj=`echo $fn | sed -e 's,^\./,,;s/\.hs$/.o/'`
+	bin=`echo $fn | sed -e 's,^\./,,;s/\.hs$//'`
+	echo "$obj: $deps"
+	grep -q "main" "$fn" && echo "$bin: `echo $deps | sed -e 's|[^ ]*src[^ ]*||g'` mk/toplibs"
+	rm -f tmp.mk
+done |
+sort |
+sed -e 's,  *, \\\n  ,g'
diff --git a/mk/haddock-i b/mk/haddock-i
new file mode 100644
--- /dev/null
+++ b/mk/haddock-i
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+# haddock-i: list haddock's -i parameters.
+#
+# Copyright (c) 2015-2018 Rudy Matela.
+# Distributed under the 3-Clause BSD licence.
+#
+# $ haddock-i <package1> <package2> ... <packageN>
+#
+# will print -i parameters necessary for haddock to link to Haddock
+# documentation installed on your system, so you can:
+#
+# $ haddock-i base template-haskell | xargs haddock <files>
+errxit() {
+	echo "$@" > /dev/stderr
+	exit 1
+}
+
+for pkg in "$@"; do
+	ghc-pkg field $pkg haddock-html,haddock-interfaces ||
+	errxit "error: haddock-i: cannot find package $pkg (ghc-pkg)"
+done |
+sed "s/.*: //" |
+sed "N;s/\n/,/;s/^/-i/"
diff --git a/mk/haskell.mk b/mk/haskell.mk
new file mode 100644
--- /dev/null
+++ b/mk/haskell.mk
@@ -0,0 +1,110 @@
+# Implicit rules for compiling Haskell code.
+#
+# Copyright (c) 2015-2018 Rudy Matela.
+# Distributed under the 3-Clause BSD licence.
+#
+# You can optionally configure the "Configuration variables" below in your main
+# makefile, e.g.:
+#
+#   GHCIMPORTDIRS = path/to/dir:path/to/another/dir
+#   GHCFLAGS = -O2 -dynamic
+#   GHC = ghc-7.6
+#   include haskell.mk
+
+
+
+# Configuration variables
+
+# GHC Parameters
+GHCIMPORTDIRS ?=
+GHCFLAGS ?=
+GHC ?= ghc
+GHCCMD = $(GHC) -i$(GHCIMPORTDIRS) $(GHCFLAGS)
+
+# Hugs Parameters
+HUGSIMPORTDIRS ?= "/usr/lib/hugs/packages/*"
+HUGSFLAGS ?=
+CPPHS_HUGS ?= cpphs-hugs --noline -D__HUGS__
+HUGS ?= hugs
+RUNHUGS ?= runhugs
+HUGSCMD    = $(HUGS)    -F"$(CPPHS_HUGS)" -P$(HUGSIMPORTDIRS) $(HUGSFLAGS)
+RUNHUGSCMD = $(RUNHUGS) -F"$(CPPHS_HUGS)" -P$(HUGSIMPORTDIRS) $(HUGSFLAGS)
+
+
+# Makefile where to keep the dependencies
+DEPMK ?= mk/depend.mk
+
+# LIB_HSS: all library Haskell files
+# ALL_HSS: all Haskell files
+# You can override ALL/LIB_HSS in your main Makefile
+LIST_LIB_HSS ?= find src -name "*.hs"
+LIST_ALL_HSS ?= find \( -path "./dist" -o -path "./.stack-work" \) -prune \
+                     -o -name "*.*hs" -print
+LIB_HSS ?= $(shell $(LIST_LIB_HSS))
+ALL_HSS ?= $(shell $(LIST_ALL_HSS))
+
+PKGNAME = $(shell cat *.cabal | grep "^name:"    | sed -e "s/name: *//")
+
+
+# Implicit rules
+%.hi %.o: %.hs
+	$(GHCCMD) $< && touch $@
+
+%: %.hs
+	$(GHCCMD) $< && touch $@
+
+.PHONY: %.ghci
+%.ghci: %.hs
+	$(GHCCMD) -O0 --interactive $<
+
+.PHONY: %.hugs
+%.hugs: %.hs
+	$(HUGSCMD) $<
+
+.PHONY: %.runhugs
+%.runhugs: %.hs
+	$(RUNHUGSCMD) $<
+
+
+# Cleaning rule (add as a clean dependency)
+.PHONY: clean-hi-o
+clean-hi-o:
+	find $(ALL_HSS) | sed -e 's/hs$$/o/'      | xargs rm -f
+	find $(ALL_HSS) | sed -e 's/hs$$/hi/'     | xargs rm -f
+	find $(ALL_HSS) | sed -e 's/hs$$/dyn_o/'  | xargs rm -f
+	find $(ALL_HSS) | sed -e 's/hs$$/dyn_hi/' | xargs rm -f
+
+
+# Update dependency file
+.PHONY: depend
+depend:
+	find $(ALL_HSS) | ./mk/ghcdeps -i$(GHCIMPORTDIRS) $(GHCFLAGS) > $(DEPMK)
+
+# haddock rules
+haddock: doc/index.html
+
+clean-haddock:
+	rm -f doc/*.{html,css,js,png,gif,json} README.html
+
+upload-haddock:
+	@echo "use \`cabal upload -d' instead"
+	@echo "(but 1st: cabal install --only-dependencies --enable-documentation)"
+	@echo "(to just compile docs: cabal haddock --for-hackage)"
+	@echo "(on Arch Linux, use: cabal haddock --for-hackage --haddock-options=--optghc=-dynamic)"
+
+doc/index.html: $(LIB_HSS)
+	./mk/haddock-i base template-haskell | xargs \
+	haddock --html -odoc $(LIB_HSS) $(HADDOCKFLAGS) --title=$(PKGNAME)
+
+# lists all Haskell source files
+list-all-hss:
+	@find $(ALL_HSS)
+
+# lists library Haskell source files
+list-lib-hss:
+	@find $(LIB_HSS)
+
+show-pkgname:
+	@echo $(PKGNAME)
+
+include $(DEPMK)
diff --git a/src/Test/Framework/Providers/LeanCheck.hs b/src/Test/Framework/Providers/LeanCheck.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Framework/Providers/LeanCheck.hs
@@ -0,0 +1,142 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+-- |
+-- Module      : Test.Framework.Providers.LeanCheck
+-- Copyright   : (c) 2018 Rudy Matela
+-- License     : 3-Clause BSD  (see the file LICENSE)
+-- Maintainer  : Rudy Matela <rudy@matela.com.br>
+--
+-- LeanCheck support for test-framework (Test.Framework).
+--
+-- Here's how your @test.hs@ might look like:
+--
+-- > import Test.Framework
+-- > import Test.Framework.Providers.LeanCheck as LC
+-- > import Data.List
+-- >
+-- > main :: IO ()
+-- > main = defaultMain tests
+-- >
+-- > tests :: [Test]
+-- > tests =
+-- >   [ LC.testProperty "sort . sort == sort"
+-- >       $ \xs -> sort (sort xs :: [Int]) == sort xs
+-- >   , LC.testProperty "sort == id" -- not really, should fail
+-- >       $ \xs -> sort (xs :: [Int]) == xs
+-- >   ]
+--
+-- The output for the above program is:
+--
+-- > ./eg/test
+-- > sort . sort == sort: [OK, passed 100 tests.]
+-- > sort == id: [Failed]
+-- > *** Failed! Falsifiable (after 7 tests):
+-- > [1,0]
+-- >
+-- >          Properties  Total
+-- >  Passed  1           1
+-- >  Failed  1           1
+-- >  Total   2           2
+--
+-- Use @-a@ or @--maximum-generated-tests@ to configure
+-- the maximum number of tests for each property.
+--
+-- > $ ./eg/test -a5
+-- > sort . sort == sort: [OK, passed 5 tests.]
+-- > sort == id: [OK, passed 5 tests.]
+-- >
+-- >          Properties  Total      
+-- >  Passed  2           2          
+-- >  Failed  0           0          
+-- >  Total   2           2          
+--
+-- Since LeanCheck is enumerative,
+-- you may want to increate the default number of tests (100).
+-- Arbitrary rule of thumb:
+--
+-- * between 200 to 500 on a developer machine;
+-- * between 1000 and 5000 on the CI.
+--
+-- Your mileage may vary.
+--
+-- Please see the documentation of
+-- "Test.LeanCheck" and "Framework.Providers"
+-- for more details.
+module Test.Framework.Providers.LeanCheck
+  ( testProperty
+  )
+where
+
+import Test.Framework.Providers.API
+import Test.LeanCheck
+import Control.Exception (SomeException, catch, evaluate)
+
+-- | List of test results for a given property
+newtype Results = Results [([String],Bool)]
+
+-- | The ultimate test result for a given property
+data Result = OK        Int
+            | Falsified Int [String]
+            | Exception Int [String] String
+  deriving Eq
+
+instance Show Result where
+  show (OK n)              =  "OK, passed " ++ show n ++ " tests."
+  show (Falsified i ce)    =  "*** Failed! Falsifiable (after "
+                           ++ show i ++ " tests):\n" ++ joinArgs ce
+  show (Exception i ce e)  =  "*** Failed! Exception '" ++ e
+                           ++ "' (after " ++ show i ++ " tests):\n"
+                           ++ joinArgs ce
+
+-- | Given a 'Testable' property, returns a test-framework test.
+--   For example, place the following in a 'TestGroup' list:
+--
+-- > testProperty "sort . sort == sort" $
+-- >   \xs -> sort (sort xs :: [Int]) == sort xs
+--
+-- You may want to import this module qualified and use @LC.TestProperty@
+-- if mixing "Test.LeanCheck" tests
+-- with those of other property testing libraries.
+testProperty :: Testable a => TestName -> a -> Test
+testProperty name = Test name . Results . results
+
+-- | The current version does not 'runImprovingIO'.
+--   So progress is only seen between properties, but not within properties.
+instance Testlike Int Result Results where
+  runTest topts results = do
+    let m = unK $ topt_maximum_generated_tests topts
+    result <- resultIO m results
+    return (Finished result, return ())
+  testTypeName _ = "Properties"
+
+instance TestResultlike Int Result where
+  testSucceeded (OK _)  =  True
+  testSucceeded _       =  False
+
+resultsIO :: Int -> Results -> [IO Result]
+resultsIO n (Results results) = zipWith torio [1..] $ take n results
+  where
+    tor i (_,True) = OK i
+    tor i (as,False) = Falsified i as
+    torio i r@(as,_) = evaluate (tor i r)
+       `catch` \e -> let _ = e :: SomeException
+                     in return (Exception i as (show e))
+
+resultIO :: Int -> Results -> IO Result
+resultIO n = computeResult . resultsIO n
+  where
+  computeResult []  = error "resultIO: no results, empty Listable enumeration?"
+  computeResult [r] = r
+  computeResult (r:rs) = r >>= \r -> case r of
+                                     (OK _) -> computeResult rs
+                                     _      -> return r
+
+-- joins the counter-example arguments
+joinArgs :: [String] -> String
+joinArgs ce | any ('\n' `elem`) ce = unlines $ map chopBreak ce
+            | otherwise            = unwords ce
+
+-- chops a line break at the end if there is any
+chopBreak :: String -> String
+chopBreak [] = []
+chopBreak ['\n'] = []
+chopBreak (x:xs) = x:chopBreak xs
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,15 @@
+# stack.yaml docs:
+# https://docs.haskellstack.org/en/stable/yaml_configuration/
+
+# resolver: nightly-2015-09-21
+# resolver: ghc-7.10.2
+resolver: lts-12.7
+
+packages:
+- .
+
+extra-deps: []
+
+flags: {}
+
+extra-package-dbs: []
diff --git a/test-framework-leancheck.cabal b/test-framework-leancheck.cabal
new file mode 100644
--- /dev/null
+++ b/test-framework-leancheck.cabal
@@ -0,0 +1,63 @@
+-- Cabal file for test-framework-leancheck
+name:                test-framework-leancheck
+version:             0.0.1
+synopsis:            LeanCheck support for test-framework.
+description:
+  LeanCheck support for test-framework.
+  .
+  This package can be used to incorporate LeanCheck tests
+  into test-framework test suites by means of the
+  @Test.Framework.Providers.LeanCheck.testProperty@ function.
+  .
+  Please see the Haddock documentation and README for more details.
+
+homepage:            https://github.com/rudymatela/test-framework-leancheck#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Rudy Matela <rudy@matela.com.br>
+maintainer:          Rudy Matela <rudy@matela.com.br>
+category:            Testing
+build-type:          Simple
+cabal-version:       1.18
+
+extra-doc-files: README.md
+               , TODO.md
+extra-source-files: .gitignore
+                  , eg/minimal.hs
+                  , Makefile
+                  , mk/depend.mk
+                  , mk/haskell.mk
+                  , mk/ghcdeps
+                  , mk/haddock-i
+                  , mk/All.hs
+                  , mk/Toplibs.hs
+                  , stack.yaml
+                  , tests/test-sdist
+                  , .travis.yml
+tested-with: GHC==8.4
+           , GHC==8.2
+           , GHC==8.0
+           , GHC==7.10
+
+
+source-repository head
+  type:           git
+  location:       https://github.com/rudymatela/test-framework-leancheck
+
+source-repository this
+  type:           git
+  location:       https://github.com/rudymatela/test-framework-leancheck
+  tag:            v0.0.1
+
+library
+  exposed-modules:     Test.Framework.Providers.LeanCheck
+  hs-source-dirs:      src
+  build-depends:       base >= 4 && < 5, test-framework, leancheck
+  default-language:    Haskell2010
+
+test-suite test
+  type:                exitcode-stdio-1.0
+  main-is:             test.hs
+  hs-source-dirs:      tests
+  build-depends:       base >= 4 && < 5, test-framework, leancheck, test-framework-leancheck
+  default-language:    Haskell2010
diff --git a/tests/test-sdist b/tests/test-sdist
new file mode 100644
--- /dev/null
+++ b/tests/test-sdist
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# test-sdist: tests the package generated by "cabal sdist".
+#
+# Copyright (c) 2015-2018 Rudy Matela.
+# Distributed under the 3-Clause BSD licence.
+pkgver=` cat *.cabal | grep "^version:" | sed -e "s/version: *//"`
+pkgname=`cat *.cabal | grep "^name:"    | sed -e "s/name: *//"`
+pkg=$pkgname-$pkgver
+set -x
+cabal sdist &&
+cd dist &&
+if [ -d ../.git ]
+then
+	# on git repo, test if files are the same
+	git -C .. ls-files                                      | sort > ls-git   &&
+	tar -tf $pkg.tar.gz | grep -v "/$" | sed -e "s,$pkg/,," | sort > ls-cabal &&
+	diff -rud ls-git ls-cabal &&
+	rm -f ls-git ls-cabal
+else
+	# outside of git repo, test build
+	rm -rf $pkg/ &&
+	tar -xzf $pkg.tar.gz &&
+	cd $pkg/ &&
+	cabal configure --enable-tests --enable-benchmarks &&
+	cabal build &&
+	cabal test
+fi
diff --git a/tests/test.hs b/tests/test.hs
new file mode 100644
--- /dev/null
+++ b/tests/test.hs
@@ -0,0 +1,18 @@
+-- Copyright (c) 2018 Rudy Matela.
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+{-# LANGUAGE CPP #-}
+import Test.Framework
+import Test.Framework.Providers.LeanCheck as LC
+
+import Data.List (sort)
+
+main :: IO ()
+main = defaultMain tests
+
+tests :: [Test]
+tests =
+  [ testProperty "sort . sort == sort"
+      $ \xs -> sort (sort xs :: [Int]) == sort xs
+  , testProperty "x + x == 2 * x"
+      $ \x -> x + x == 2 * (x :: Int)
+  ]
